Skip to content

feat(auth): add Grok authentication support#305

Merged
skulidropek merged 16 commits into
ProverCoderAI:mainfrom
konard:issue-304-3b5ced26375c
May 18, 2026
Merged

feat(auth): add Grok authentication support#305
skulidropek merged 16 commits into
ProverCoderAI:mainfrom
konard:issue-304-3b5ced26375c

Conversation

@konard
Copy link
Copy Markdown
Contributor

@konard konard commented May 15, 2026

Fixes #304

Summary

  • Adds Grok as a first-class auth provider across CLI parsing, API contracts, auth menus, project auth snapshots, prompt/skill provider schemas, and --auto grok agent selection.
  • Adds Grok credential use cases for API-key login, OAuth/browser login through the official Grok CLI device-code flow, status, logout, .docker-git/.orch/auth/grok/<label> storage, and state auto-sync.
  • Extends generated project templates to install the official xAI Grok CLI from https://x.ai/cli/install.sh, configure ~/.grok, disable sandbox by default, wire Playwright MCP, provide the intentional container-local sudo policy, and support Grok project rules/system prompt hooks.
  • Guards generated Grok entrypoint shell against missing optional GROK_AUTH_LABEL, GROK_API_KEY, GROK_DEPLOYMENT_KEY, and XAI_API_KEY under set -u.
  • Keeps Grok selected-label state stable by replacing migrated ~/.grok files with symlinks into the selected .orch/auth/grok/<label> account directory.
  • Propagates Grok auth permission-fix failures as typed command errors instead of silently treating a partial login as successful.

Reproduction / Verification

  1. Before this change, auth grok ..., --auto grok, Grok provider schemas, and Grok template auth paths were absent.
  2. CI reproduced generated entrypoint failures from missing optional Grok env under set -u.
  3. Coverage now checks Grok parser commands, Grok API-key credential materialization, official xAI installer rendering, device-code login args, template rendering, selected-label symlink wiring, auto-agent selection, API agent command rendering, and unescaped Grok bash defaults.

Mathematical Guarantees

Invariants

  • forall label: authGrokLogin(label, key) -> exists .docker-git/.orch/auth/grok/normalize(label)/.api-key
  • forall project: grokAuthLabel(project) -> Grok credentials are mounted from the selected label only
  • forall generated Grok entrypoint: unset(optional_grok_env) -> no nounset failure during bootstrap
  • forall Grok agent run: command includes sandbox disabled and Playwright MCP isolation enabled
  • forall credential status checks: no API key value is logged

Preconditions

  • API-key login requires a non-empty key provided by the auth boundary.
  • OAuth login requires Docker availability because it executes grok login --device-auth in the auth image.

Postconditions

  • Grok project templates contain .grok/settings.json with Playwright MCP and sandbox off.
  • Grok logout removes .api-key, .env, and .grok credential material for the selected label.
  • Grok env bridge exports empty values for missing optional API-key vars instead of failing shell startup.
  • Grok auth permission normalization either succeeds or returns a typed error.

Tests

  • bun run --cwd packages/lib test tests/core/templates.test.ts tests/usecases/auth-grok.test.ts
  • bun run --filter @effect-template/lib typecheck
  • bun run --filter @prover-coder-ai/docker-git typecheck
  • bun x @ton-ai-core/vibecode-linter src/core/templates-entrypoint/grok.ts from packages/lib
  • bun x @ton-ai-core/vibecode-linter src/usecases/auth-grok-oauth.ts from packages/lib
  • bun x @ton-ai-core/vibecode-linter src/lib/usecases/auth-grok-oauth.ts from packages/app
  • Direct ESLint for packages/app/src/lib/core/templates-entrypoint/grok.ts and packages/app/src/docker-git/cli/usage.ts
  • jscpd src --silent from packages/lib
  • GitHub Actions on the previous follow-up SHA passed all checks; current SHA re-runs are pending.

Notes

  • Official Grok CLI source: https://x.ai/news/grok-build-cli
  • Local caveat: the vibecode-linter wrapper can be OOM-killed locally on the large mirrored app Grok template file, so that file was validated through direct ESLint plus app typecheck; CI runs the full lint job.

Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: ProverCoderAI#304
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 02c23bad-4193-4dd2-8083-49eb77397044

📥 Commits

Reviewing files that changed from the base of the PR and between 0c29c14 and bb3f1ba.

📒 Files selected for processing (2)
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
packages/app/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

APP layer works only with API and does not have access to LIB

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:53:28.056Z
Learning: Runtime contract: docker-git is host-Docker-backed by design; the controller container talks to the host Docker daemon via bind-mounted /var/run/docker.sock with no isolated Docker-in-Docker runtime
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:53:28.056Z
Learning: Projects are stored in ~/.docker-git by default
🔇 Additional comments (10)
packages/lib/src/usecases/auth-grok-oauth.ts (5)

44-78: TSDoc добавлен, валидация пути — низкоприоритетна.

TSDoc документация добавлена согласно прошлому комментарию. Валидация containerPath не была реализована, но это приемлемо: путь контролируется внутренней конфигурацией, не пользовательским вводом, и Docker сам вернёт ошибку при некорректном пути.


1-42: LGTM!


80-96: LGTM!


98-120: LGTM!


122-164: LGTM!

packages/app/src/lib/usecases/auth-grok-oauth.ts (5)

1-42: LGTM!


44-78: LGTM!


80-96: LGTM!


98-120: LGTM!


122-164: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Полная поддержка провайдера Grok: OAuth и API‑key в UI, CLI и проектных сценариях; Grok‑prompts и Grok‑skills; новые опции меток токенов при создании/применении проектов.
  • Improvements

    • Автовыбор агента учитывает Grok; шаблоны запуска, entrypoint и Dockerfile включают Grok‑блоки; CLI‑help и флаги расширены для Gemini/Grok.
    • Улучшена работа с портами в e2e‑скриптах (поиск свободных портов).
  • Tests

    • Добавлены и расширены unit и интеграционные тесты для Grok‑функций.

Извините — мне нужно пересобрать скрытый артефакт обзора, но для этого требуется больше времени и аккуратная работа с полным списком rangeId из запроса. Разрешите мне сейчас пересобрать его корректно (я использую все rangeId ровно по одному и сгруппирую их в семантические чекпоинты). Ответ займет одну следующую итерацию.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@konard konard changed the title [WIP] Реализовать поддержку авторизации grok feat(auth): add Grok authentication support May 15, 2026
@konard konard marked this pull request as ready for review May 15, 2026 14:44
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 32

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
packages/app/src/docker-git/menu-project-auth.ts (1)

132-138: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Замените if-цепочку на Match.exhaustive для исчерпывающего анализа ProjectAuthMenuAction.

Текущий код (строки 132-141) не обеспечивает compile-time гарантию покрытия всех вариантов union. При добавлении новой connect- или disconnect-ветки в ProjectAuthFlow новое значение молча попадёт в startProjectAuthPrompt, что приведёт к логической ошибке.

В том же модуле функция projectAuthSuccessMessage демонстрирует правильное применение Match.value(...).pipe(Match.when(...), Match.exhaustive) — используйте тот же паттерн здесь.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/menu-project-auth.ts` around lines 132 - 138,
Replace the manual if-chain checking action (ProjectGithubDisconnect |
ProjectGitDisconnect | ProjectClaudeDisconnect | ProjectGeminiDisconnect |
ProjectGrokDisconnect) with an exhaustive pattern match using
Match.value(action).pipe(..., Match.exhaustive) to guarantee compile-time
coverage of the ProjectAuthMenuAction union; follow the same pattern used in
projectAuthSuccessMessage (Match.value(...).pipe(Match.when(...),
Match.exhaustive)), creating Match.when clauses for each connect/disconnect
branch and delegating to startProjectAuthPrompt or the appropriate disconnect
handling so any new union variant will force a compile-time handling decision
rather than silently falling through.
packages/api/src/services/federation.ts (1)

1694-1699: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Критическая проблема: отсутствие exhaustive анализа типа провайдера.

Функция resolveAgentProvider использует тернарный оператор вместо exhaustive Match, что может пропустить неподдерживаемые значения AgentProvider. Согласно coding guidelines, все union types должны анализироваться через Match.exhaustive().

🐛 Предлагаемое исправление с exhaustive Match
 const resolveAgentProvider = (
   subscription: FollowSubscription | undefined
 ): AgentProvider => {
   const raw = subscription?.agentProvider ?? process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"]
-  return raw === "claude" || raw === "opencode" || raw === "grok" || raw === "custom" ? raw : "codex"
+  return Match.value(raw).pipe(
+    Match.when("claude", () => "claude" as const),
+    Match.when("opencode", () => "opencode" as const),
+    Match.when("grok", () => "grok" as const),
+    Match.when("custom", () => "custom" as const),
+    Match.when("codex", () => "codex" as const),
+    Match.orElse(() => "codex" as const)
+  )
 }

Согласно coding guidelines: "Use exhaustive pattern matching with Effect.Match instead of switch statements."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/federation.ts` around lines 1694 - 1699, The
resolver resolveAgentProvider must use Effect.Match.exhaustive to perform
exhaustive pattern matching on the raw provider string instead of the current
ternary; update the function to compute raw from subscription?.agentProvider ||
process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"] and then call Match.exhaustive
with cases for "claude", "opencode", "grok", "custom", and "codex" (mapping each
to the corresponding AgentProvider) and an explicit default branch that returns
"codex" so all union values are handled; ensure you import Effect.Match and keep
the function signature types (FollowSubscription, AgentProvider) unchanged.
packages/api/src/services/project-auth.ts (1)

173-197: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Одобряю рефакторинг, но отсутствует TSDoc.

Параметризация hasApiKeyInEnvFile с аргументом key — отличное улучшение для переиспользования кода. Однако функция не имеет TSDoc документации.

📝 Предлагаемое дополнение TSDoc
+/**
+ * Checks if an environment file contains a non-empty API key.
+ *
+ * `@param` fs - FileSystem service
+ * `@param` envFilePath - Path to .env file to check
+ * `@param` key - Environment variable key name (e.g., "GEMINI_API_KEY")
+ * `@returns` Effect resolving to true if key exists with non-empty value
+ *
+ * `@pure` false
+ * `@effect` Reads filesystem
+ * `@invariant` returns false for non-existent files or empty values
+ * `@precondition` envFilePath should be normalized
+ * `@postcondition` does not modify filesystem
+ * `@complexity` O(n) where n is the number of lines in .env file
+ */
 const hasApiKeyInEnvFile = (
   fs: FileSystem.FileSystem,
   envFilePath: string,
   key: string
 ): Effect.Effect<boolean, PlatformError> =>

Согласно coding guidelines: "Document all functions with comprehensive TSDoc."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-auth.ts` around lines 173 - 197, Add a
TSDoc block to the hasApiKeyInEnvFile function that explains its purpose (checks
whether a non-empty env variable named by the `key` exists in a file), documents
parameters `fs: FileSystem.FileSystem`, `envFilePath: string`, and `key:
string`, and states the return type `Effect.Effect<boolean, PlatformError>`
along with behavior on missing files or read errors (returns false or uses
provided Effect error handling). Mention examples of expected env line formats
(e.g., KEY=value, KEY="value") and note that quotes are stripped and whitespace
trimmed so only non-empty values return true. Ensure the TSDoc appears
immediately above the hasApiKeyInEnvFile declaration.
packages/app/src/docker-git/menu-auth.ts (1)

89-107: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Рефакторинг: использовать exhaustive Match вместо boolean-цепочки.

Текущий код определяет suspendTui через ||-цепочку проверок view.flow. Это не обеспечивает exhaustive анализ и может пропустить будущие OAuth-потоки. Согласно coding guidelines, все union types должны анализироваться через .exhaustive() или Match.exhaustive().

♻️ Предлагаемый рефакторинг с exhaustive Match
 const submitAuthPrompt = (view: AuthPromptView, context: AuthInputContext) => {
   const steps = authViewSteps(view.flow)
+  const suspendTui = Match.value(view.flow).pipe(
+    Match.when("GithubOauth", () => true),
+    Match.when("ClaudeOauth", () => true),
+    Match.when("ClaudeLogout", () => true),
+    Match.when("GeminiOauth", () => true),
+    Match.when("GrokOauth", () => true),
+    Match.orElse(() => false)
+  )
   submitPromptStep(
     view,
     steps,
     context,
     () => {
       startAuthMenuWithSnapshot(view.snapshot, context)
     },
     (nextValues) => {
       const label = defaultLabel(nextValues["label"] ?? "")
       const effect = resolveAuthPromptEffect(view, context.state.cwd, nextValues)
-      runAuthPromptEffect(effect, view, label, { ...context, cwd: context.state.cwd }, {
-        suspendTui: view.flow === "GithubOauth" || view.flow === "ClaudeOauth" || view.flow === "ClaudeLogout" ||
-          view.flow === "GeminiOauth" || view.flow === "GrokOauth"
-      })
+      runAuthPromptEffect(effect, view, label, { ...context, cwd: context.state.cwd }, { suspendTui })
     }
   )
 }

Согласно coding guidelines: "Use exhaustive pattern matching with Effect.Match instead of switch statements."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/menu-auth.ts` around lines 89 - 107, Replace the
boolean OR chain used to compute suspendTui inside submitAuthPrompt with an
exhaustive pattern match over view.flow (use Effect.Match.exhaustive or
Match.exhaustive per coding guidelines) so all union cases are handled; update
the suspendTui argument passed to runAuthPromptEffect (inside submitAuthPrompt)
to be the result of that exhaustive match, and ensure the match returns a
boolean for each flow variant so future OAuth flows will cause a compile-time
failure if not handled.
packages/app/src/lib/core/templates-entrypoint/rtk.ts (1)

9-44: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Несоответствие FORMAT THEOREM и реализации: grok не поддерживается RTK.

FORMAT THEOREM (строка 9) обещает configured(codex, claude, gemini, grok, opencode), однако RTK не поддерживает флаг --grok. Строки 31–32 создают директорию ~/.grok, но строк 41–44 содержат только инициализацию для codex, claude, gemini и opencodegrok отсутствует.

Решение: либо удалите grok из FORMAT THEOREM и директорию ~/.grok, либо отложите эту часть PR до добавления поддержки --grok в RTK. В текущем состоянии математический инвариант нарушен.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/templates-entrypoint/rtk.ts` around lines 9 - 44,
The FORMAT THEOREM claims RTK configures "grok" but RTK has no --grok flag, so
update renderEntrypointRtkConfig to remove grok references: change the FORMAT
THEOREM token list to configured(codex, claude, gemini, opencode) and delete
"/home/__SSH_USER__/.grok" from the mkdir and chown paths in the template body
(and any related log text), leaving the four actual docker_git_rtk_init_as_user
invocations unchanged; this preserves the invariant without adding unsupported
RTK behavior.
packages/api/src/services/auth-menu.ts (1)

131-146: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Рекомендуется рефакторинг: заменить вложенные тернарные операторы на Match pattern.

Глубоко вложенные тернарные операторы (5+ уровней) трудно читать и поддерживать. Согласно coding guidelines, следует использовать Match.value().pipe() с .exhaustive() для исчерпывающего анализа union-типов.

♻️ Предлагаемый рефакторинг с использованием Match pattern
+import { Match } from "effect"
+
 const syncMessage = (request: AuthMenuRequest): string =>
-  request.flow === "GithubRemove"
-    ? `chore(state): auth gh logout ${canonicalLabel(request.label)}`
-    : request.flow === "GitSet"
-      ? `chore(state): auth git ${canonicalLabel(request.label)}`
-      : request.flow === "GitRemove"
-        ? `chore(state): auth git logout ${canonicalLabel(request.label)}`
-        : request.flow === "ClaudeLogout"
-          ? `chore(state): auth claude logout ${canonicalLabel(request.label)}`
-          : request.flow === "GeminiApiKey"
-            ? `chore(state): auth gemini ${canonicalLabel(request.label)}`
-            : request.flow === "GeminiLogout"
-              ? `chore(state): auth gemini logout ${canonicalLabel(request.label)}`
-              : request.flow === "GrokApiKey"
-                ? `chore(state): auth grok ${canonicalLabel(request.label)}`
-                : `chore(state): auth grok logout ${canonicalLabel(request.label)}`
+  Match.value(request.flow).pipe(
+    Match.when("GithubRemove", () => `chore(state): auth gh logout ${canonicalLabel(request.label)}`),
+    Match.when("GitSet", () => `chore(state): auth git ${canonicalLabel(request.label)}`),
+    Match.when("GitRemove", () => `chore(state): auth git logout ${canonicalLabel(request.label)}`),
+    Match.when("ClaudeLogout", () => `chore(state): auth claude logout ${canonicalLabel(request.label)}`),
+    Match.when("GeminiApiKey", () => `chore(state): auth gemini ${canonicalLabel(request.label)}`),
+    Match.when("GeminiLogout", () => `chore(state): auth gemini logout ${canonicalLabel(request.label)}`),
+    Match.when("GrokApiKey", () => `chore(state): auth grok ${canonicalLabel(request.label)}`),
+    Match.when("GrokLogout", () => `chore(state): auth grok logout ${canonicalLabel(request.label)}`),
+    Match.exhaustive
+  )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/auth-menu.ts` around lines 131 - 146, The
syncMessage function currently uses deeply nested ternary operators to map
AuthMenuRequest.flow to commit message strings; replace that chain with a clear
Match.value() pattern match over request.flow (using
Match.value(request.flow).pipe(...).exhaustive()) that returns the same strings
by calling canonicalLabel(request.label) where needed; update syncMessage to
switch on each flow case (GithubRemove, GitSet, GitRemove, ClaudeLogout,
GeminiApiKey, GeminiLogout, GrokApiKey, GrokLogout) and return the exact
corresponding message for each case, ensuring exhaustiveness for the union type
AuthMenuRequest so future flows cause a compile-time error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/auth-terminal-runner.ts`:
- Around line 7-8: parseFlow currently maps any invalid or undefined value to
"ClaudeOauth" silently; change it to fail-fast instead: in the parseFlow
function (returning AuthTerminalRunnerFlow) validate that value is exactly one
of "ClaudeOauth" | "GeminiOauth" | "GrokOauth" and return it, otherwise throw a
descriptive Error (include the invalid value) so callers don't silently proceed
with the wrong provider; update any call sites expecting a default accordingly.

In `@packages/api/src/services/auth-terminal-sessions.ts`:
- Around line 72-76: The nested ternary that maps request.flow to a command
string should be replaced with an exhaustive Match-based switch to ensure
compile-time coverage of all AuthTerminalFlow variants: use
Match.value(request.flow).pipe(...) with Match.when handlers for "ClaudeOauth",
"GeminiOauth", and "GrokOauth" that each return the appropriate backtick string
including the existing suffix, and finish with Match.exhaustive() so new flows
cannot silently fall through to the wrong label; update the return expression
accordingly where request.flow is used.

In `@packages/api/src/services/project-auth.ts`:
- Around line 239-258: Add a TSDoc comment for the hasGrokAccountCredentials
function describing its purpose (checks for GROK API credentials in three
locations), its parameters (fs: FileSystem.FileSystem, accountPath: string), the
return type (Effect.Effect<boolean, PlatformError> indicating success boolean or
PlatformError), and the behavior/side-effects (it checks .api-key via
hasFileAtPath, GROK_API_KEY in .env via hasApiKeyInEnvFile, and OAuth token in
.grok/user-settings.json via hasNonEmptyOauthToken), and note possible errors
propagated from PlatformError; place the comment immediately above the
hasGrokAccountCredentials declaration.

In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`:
- Around line 28-71: Add full TSDoc and functional comments to the CORE pure
function buildTemplateConfigBase: include `@pure` (true/false), `@effect` (required
services or "none"), `@invariant` (any mathematical invariants), `@precondition`
(valid shape/constraints of input Pick<BuildTemplateConfigInput,...>),
`@postcondition` (returned object matches CreateCommand["config"] subset), and
`@complexity` (time and space). Also add the functional comment block with CHANGE,
WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT THEOREM, PURITY, INVARIANT,
COMPLEXITY describing intent, rationale, references and guarantees for
buildTemplateConfigBase and reference the function name and the exact fields it
maps (containerName, serviceName, sshUser, sshPort, repoUrl, repoRef, targetDir,
volumeName, dockerGitPath, authorizedKeysPath, envGlobalPath, envProjectPath,
codexAuthPath, codexSharedAuthPath, codexHome, geminiAuthPath, geminiHome,
grokAuthPath, grokHome) to make clear mapping and postconditions.
- Around line 73-93: The exported CORE function buildTemplateConfig lacks the
required comprehensive TSDoc; add a full TSDoc block immediately above the
exported function buildTemplateConfig describing the function purpose, each
parameter in BuildTemplateConfigInput (`@param`), the return type
CreateCommand["config"] (`@returns`), and include the required tags: `@pure`,
`@effect` (list any external deps such as buildTemplateConfigBase and
defaultTemplateConfig), `@invariant` (describe any invariants about returned
config), `@precondition` (validations on input fields like cpuLimit/ramLimit/gpu),
`@postcondition` (what properties will always be present in the returned config),
and `@complexity` (Big-O for any significant work); ensure references to internal
symbols buildTemplateConfigBase and defaultTemplateConfig are mentioned in the
text so readers can locate dependencies.

In `@packages/app/src/lib/core/auto-agent-flags.ts`:
- Line 23: Update the error string that sets the `reason` (currently "expected
one of: claude, codex, gemini, grok") to include "auto" so it matches the
accepted mode (`requested === "auto"`); ensure the `reason` value lists all
supported modes including "auto" and stays synchronized with any validation
logic that references `requested`.

In `@packages/app/src/lib/core/command-builders-template.ts`:
- Around line 28-94: The two exported functions buildTemplateConfigBase and
buildTemplateConfig are missing the required comprehensive TSDoc and functional
markers; add TSDoc blocks above each function documenting parameters and return
types and include the mandated tags/markers: `@pure`, `@invariant`, `@precondition`,
`@postcondition`, `@complexity` (with O-notation), and the functional comment fields
(CHANGE, WHY, QUOTE or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY
(CORE|SHELL), EFFECT signature if applicable, INVARIANT, COMPLEXITY). Ensure the
docs reference the function signature symbols buildTemplateConfigBase and
buildTemplateConfig and succinctly describe input: BuildTemplateConfigInput and
output: CreateCommand["config"], plus any important invariants (e.g., which
fields are mapped/copied), and place the blocks immediately above each function
declaration.

In `@packages/app/src/lib/core/templates/docker-compose.ts`:
- Around line 222-224: Комментарий после переменных окружения не соответствует
своему назначению: переменная fragments.maybeGrokAuthLabelEnv снабжена
комментарием, который сейчас стоит одновременно после
fragments.maybeAgentModeEnv и fragments.maybeAgentAutoEnv, что вводит в
заблуждение; исправьте шаблон в docker-compose.ts так, чтобы комментарий "#
Optional Grok account label selector (maps to GROK_AUTH_LABEL)" стоял
непосредственно после fragments.maybeGrokAuthLabelEnv, а для
fragments.maybeAgentModeEnv и fragments.maybeAgentAutoEnv добавьте свои
отдельные комментарии (или уберите их), чтобы каждый комментарий однозначно
относился к соответствующей переменной.

In `@packages/app/src/lib/core/templates/dockerfile.ts`:
- Around line 113-114: Строка, которая маскирует провал установки Grok CLI ("RUN
grok --version >/dev/null || true") должна быть исправлена: замените или удалите
конструкцию "|| true" и/или уберите перенаправление в /dev/null so that the
subsequent check fails the build when the CLI is not present; specifically
update the two Dockerfile RUN commands ("RUN npm install -g grok-dev@latest
--force" and the following "RUN grok --version >/dev/null || true") so that the
image build exits non‑zero if "grok --version" fails (e.g., use plain "RUN grok
--version" or an explicit check like "RUN command -v grok >/dev/null" without
"|| true").

In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 209-214: The code currently runs runCommandExitCode with "chmod -R
777" on credentialsDir which makes secrets world-readable/writable; change to
set owner-only permissions (e.g., directories 700 and files 600) or use a safe
recursive chmod like "chmod -R u+rwX,go-rwx" so only the owner can
read/write/execute, and remove the blanket Effect.orElse(() =>
Effect.succeed(0)) that silences failures so permission errors surface; update
the same pattern in the similar block referenced later (the other chmod usage
around the 230-255 region) to use the secure permission command and proper error
handling, locating the changes around the runCommandExitCode and credentialsDir
symbols.
- Around line 193-206: The cleanup fallback currently swallows errors
(removeFallback is defined with Effect.orElse(() => Effect.void)), so if both
fs.remove(credentialsDir) and the docker fallback fail the effect is treated as
success and code proceeds; remove the swallowing wrapper from removeFallback
(keep runCommandExitCode(...).pipe(Effect.asVoid) but do not orElse to
Effect.void) so that if the docker fallback fails the overall effect fails and
propagation stops; ensure fs.remove(...).pipe(Effect.orElse(() =>
removeFallback)) remains so the fallback is attempted but failures are not
suppressed.
- Around line 165-170: The current check in hasGrokCredentials (which uses
isRegularFile(grokUserSettingsPath(accountPath)) and then treats any non-empty
user-settings.json as valid) incorrectly treats bootstrap files created by
writeInitialGrokSettings(..., null) as authenticated; change hasGrokCredentials
to parse the JSON from fs.readFileString(grokUserSettingsPath(accountPath)) and
verify presence of real credential fields (e.g., non-null/non-empty token,
apiKey, or username fields your code uses) rather than mere file existence or
non-empty content, so resolveGrokAuthMethod() won't return "user-settings" for
bootstrap files; apply the same validation logic where similar checks exist
(around the other occurrence mentioned, lines ~250-255) and use
grokUserSettingsPath, hasGrokCredentials, resolveGrokAuthMethod, and
writeInitialGrokSettings names to locate the changes.
- Around line 55-63: The Dockerfile RUN step currently installs grok-dev using
the floating tag and force flag; replace the unstable install invocation that
uses "grok-dev@latest" and "--force" with a pinned install of grok-dev version
1.1.6 so the Docker build is deterministic (locate the RUN npm install -g
grok-dev... line in the auth-grok helper Docker snippet and change it to install
grok-dev@1.1.6 without --force).

In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 79-101: The fixGrokAuthPermissions function currently runs a
docker alpine container to chmod -R 777 on the Grok auth directory; change this
to set restrictive permissions or fix ownership instead: replace the chmod args
in fixGrokAuthPermissions to use "chmod -R 700" (or "750" if group-read is
required) or, preferably, run "chown -R <user>:<group>" inside the container
before applying more restrictive chmod; ensure the CommandFailedError and
runCommandWithExitCodes call remain unchanged but update the args array passed
to docker to reflect the safer permission/ownership commands.
- Around line 38-43: Replace the unsupported env vars in the env array
(currently `HOME=${containerPath}`, `NO_BROWSER=true`, `GROK_NO_BROWSER=true`,
`MCP_PLAYWRIGHT_ISOLATED=1`) with a supported approach: look up the
grok/grok-dev CLI docs and either (a) pass the official CLI flag to disable
browser opening (e.g., run the "grok login" command with the documented flag
such as "--no-browser" or the exact flag/name you find) or (b) if no flag/ENV
exists, remove `NO_BROWSER`/`GROK_NO_BROWSER` and implement a headless fallback
in the auth-grok-oauth flow that spawns "grok login", captures the printed
authorization URL from stdout, prompts the user to open it manually and paste
the callback, and include a runtime version check of grok-dev to ensure the
chosen method is supported; update the code that constructs the env array and
the place that calls "grok login" accordingly.

In `@packages/app/src/lib/usecases/auth-grok.ts`:
- Line 40: The chmod call for apiKeyFilePath is currently wrapped with
orElseSucceed which suppresses failures; change this so permission-setting
errors are not swallowed—remove the orElseSucceed around
fs.chmod(apiKeyFilePath, 0o600) (or replace it with explicit error handling that
logs and rethrows) so that failures propagate and cause the operation to fail;
locate the call to fs.chmod and the use of orElseSucceed in
usecases/auth-grok.ts (reference symbols: fs.chmod, apiKeyFilePath,
orElseSucceed) and ensure the code fails on chmod errors rather than continuing
silently.

In `@packages/app/tests/docker-git/parser-auth.test.ts`:
- Around line 22-41: Add a fast-check property-based test that repeatedly runs
parseOrThrow for Grok auth commands with generated valid label strings and
asserts the invariants instead of a single static case: generate labels
(non-empty, trimmed, maybe alphanumeric/spaces) and for each value call
parseOrThrow(["auth","grok","login","--label", label, "--web"]),
parseOrThrow(["auth","grok","status","--label", label]) and
parseOrThrow(["auth","grok","logout","--label", label]) and assert the returned
tags are AuthGrokLogin/AuthGrokStatus/AuthGrokLogout respectively, that
login.isWeb === true, and that .grokAuthPath === ".docker-git/.orch/auth/grok"
for all three results; integrate fast-check into the existing it.effect test (or
add a new one) and fail on any counterexample so the parser invariants are
validated across many generated labels.

In `@packages/lib/src/core/auto-agent-flags.ts`:
- Line 22: The error message for the --auto flag omits "auto" in the
allowed-values text; update the `reason` string in
packages/lib/src/core/auto-agent-flags.ts (the `reason` property for the --auto
flag) to include "auto" alongside "claude, codex, gemini, grok" so the hint
correctly reflects that "auto" is a valid option.

In `@packages/lib/src/core/domain.ts`:
- Line 58: The public type AgentMode was extended to include "grok" and needs a
functional comment block above the AgentMode declaration documenting the CHANGE,
WHY, QUOTE (requirement), and REF markers; update the comment for the AgentMode
type to state that "grok" was added (CHANGE), explain the architectural reason
or compatibility rationale (WHY), cite the requirement or ticket text that
mandated the addition (QUOTE), and include a reference ID (REF), ensuring the
comment is adjacent to the AgentMode type declaration to keep the public API
change discoverable.

In `@packages/lib/src/core/templates-entrypoint/agent.ts`:
- Around line 43-45: The generated AGENT_ENV_FILE currently ends up
world-readable because the script writes /etc/profile.d/grok-config.sh contents
then sets mode via "chmod 644", exposing secrets; change the post-write steps to
chown the file to the runtime user and group and tighten permissions (e.g., set
to 640 or 600) and ensure group is the runtime group used by the agent; update
the sequence around AGENT_ENV_FILE, replacing the chmod 644 usage with a chown
to the agent runtime user/group (use your runtime user symbol/variable) followed
by chmod 640 (or 600) so only the agent user/group can read the file.

In `@packages/lib/src/core/templates/docker-compose.ts`:
- Around line 221-223: Split the combined env fragment line into two separate
lines so each fragment has the correct comment: render
fragments.maybeGrokAuthLabelEnv on its own line with the "Optional Grok account
label selector (maps to GROK_AUTH_LABEL)" comment, and render
fragments.maybeAgentModeEnv and fragments.maybeAgentAutoEnv together on the next
line with a distinct comment like "Optional agent mode and auto-start
configuration"; update the template where these symbols appear so comments align
with the corresponding fragments (maybeGrokAuthLabelEnv, maybeAgentModeEnv,
maybeAgentAutoEnv).

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 113-114: В шаблоне Dockerfile замените установку неофициального
пакета и мягкую проверку на официальную установку или явное, зафиксированное
стороннее решение: вместо "RUN npm install -g grok-dev@latest --force" и "RUN
grok --version >/dev/null || true" либо (предпочтительно) скачайте и установите
официальное xAI Grok Build через curl/официальный инсталлятор (подставив
проверяемую версию/хеш), либо если оставляете сторонний пакет — уберите
"--force", зафиксируйте конкретную версию вместо "latest", удалите "|| true" и
добавьте явную проверку выхода с ошибкой при неуспешной установке; если
выбираете сторонний пакет, потребуйте security review/approval перед мерджем.

In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 208-214: The chmod 777 call in the runCommandExitCode invocation
grants excessive permissions to credentialsDir; replace it with a safer,
restrictive approach: run commands that set directories to 700 and files to 600
(e.g., use find to apply chmod 700 to all directories under credentialsDir and
chmod 600 to all files) instead of ["-R","777",credentialsDir], keeping the call
site runCommandExitCode({ cwd, command: "chmod", args: ... }) and credentialsDir
variable; preserve the Effect.orElse(() => Effect.succeed(0)) error handling
around the command(s).
- Around line 59-63: Replace the npm global install that uses an unpredictable
latest tag and --force: find occurrences of the literal string "npm install -g
grok-dev@latest --force" in the Dockerfile template generators and change them
to a pinned, explicit version like "npm install -g grok-dev@1.1.6" and remove
the "--force" flag; update each template function that emits the Dockerfile
snippet (the Dockerfile template generator(s) that produce the RUN curl ... &&
apt-get ... && npm install -g ... line) so they hardcode the stable version
instead of `@latest` and do not pass --force.

In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 79-101: The function fixGrokAuthPermissions currently runs chmod
-R 777 via runCommandWithExitCodes which grants world-writable access to Grok
credentials; change the chmod invocation in the args passed to
runCommandWithExitCodes (the array containing "chmod", "-R", "777",
containerPath) to a safe permission such as "700" (or "755" if group/other read
is required) so only the owner can read/write/execute the credentials directory;
keep the CommandFailedError creation and the Effect.tapError/Effect.orElse
handling unchanged.
- Around line 103-130: Add a TSDoc block above the exported
runGrokOauthLoginWithPrompt function that documents its purpose and behavior and
includes the required tags: `@pure`, `@effect` (describe the Effect type and failure
channels AuthError | CommandFailedError | PlatformError), `@invariant` (state
invariants such as cwd/accountPath resolution), `@precondition` (valid cwd and
accountPath, docker available), `@postcondition` (prints OAuth instructions, runs
docker auth flow, fixes permissions), and `@complexity` (time/space complexity).
Also document parameters (cwd, accountPath, options.image,
options.containerPath) and the return type (Effect.Effect<void, AuthError |
CommandFailedError | PlatformError, CommandExecutor.CommandExecutor>) so the
public API is fully covered for runGrokOauthLoginWithPrompt.
- Around line 46-67: Add full TSDoc to the exported function
buildDockerGrokAuthArgs (include `@pure`, `@effect`, `@invariant`, `@precondition`,
`@postcondition`, `@complexity`) and implement input validation for
spec.containerPath (referencing DockerGrokAuthSpec and buildDockerGrokAuthArgs)
so the function rejects or throws a clear error when containerPath is empty,
contains null bytes, contains path traversal patterns (e.g., "..") or is not an
absolute/normalized path; ensure you validate before using it in the args array
and document the precondition/postcondition that containerPath will be a
normalized absolute path and that the returned array contains the Docker run
args including the validated mount and workdir.

In `@packages/lib/src/usecases/auth-grok.ts`:
- Around line 50-62: Параметр _command в сигнатуре функции authGrokLoginCli не
используется; либо удалите его из сигнатуры (заменив экспорт на
authGrokLoginCli(): Effect.Effect<...>) либо начните явно использовать его
внутри Effect.gen (например передав необходимые поля в логи/логику) to satisfy
the interface; обновите все вызовы/auth signatures accordingly so they match the
new signature or continue accepting the parameter if required for interface
compatibility.
- Around line 76-78: The code currently calls prepareGrokCredentialsDir(...)
then immediately writeInitialGrokSettings(..., null) which can leave a null API
key on disk if the subsequent OAuth flow fails; update the flow in auth-grok.ts
so you only call writeInitialGrokSettings after the OAuth process completes
successfully (or, alternatively, perform the write as part of a transactional
sequence and remove/rollback the created settings on any OAuth error).
Concretely, move the writeInitialGrokSettings call to after the successful
return of the OAuth routine (or add a catch/finally that deletes or restores the
credentials file on failure), referencing prepareGrokCredentialsDir and
writeInitialGrokSettings to locate where to change behavior.
- Line 40: Хранится молчаливое подавление ошибки chmod при установке прав на
файл API-ключа: в месте с вызовом fs.chmod внутри usecases/auth-grok.ts удалите
использование Effect.orElseSucceed(() => void 0) и позвольте ошибке/эффекту
проброситься (или замените на явный Effect.fail с информативным сообщением),
чтобы не продолжать работу при неудачной установке прав; убедитесь, что ошибка
содержит контекст (путь файла и причину) и приводит к отказу
аутентификации/завершению процесса вместо бесшумного продолжения.

In `@packages/lib/tests/usecases/auth-grok.test.ts`:
- Around line 10-23: Добавьте краткую TSDoc над helper-функцией withTempDir,
объясняющую её назначение (создаёт временную директорию для теста и передаёт её
в callback), описывающую использование Effect.scoped для управления жизненным
циклом ресурса, перечисляющую параметр use (callback, получающий tempDir:
string) и возвращаемое значение (Effect, который может содержать результат теста
или FileSystem.FileSystem), и упомяните префикс временной директории; ссылаясь
на сimbols withTempDir, Effect.scoped и FileSystem.FileSystem, чтобы облегчить
поиск места вставки документации.

---

Outside diff comments:
In `@packages/api/src/services/auth-menu.ts`:
- Around line 131-146: The syncMessage function currently uses deeply nested
ternary operators to map AuthMenuRequest.flow to commit message strings; replace
that chain with a clear Match.value() pattern match over request.flow (using
Match.value(request.flow).pipe(...).exhaustive()) that returns the same strings
by calling canonicalLabel(request.label) where needed; update syncMessage to
switch on each flow case (GithubRemove, GitSet, GitRemove, ClaudeLogout,
GeminiApiKey, GeminiLogout, GrokApiKey, GrokLogout) and return the exact
corresponding message for each case, ensuring exhaustiveness for the union type
AuthMenuRequest so future flows cause a compile-time error.

In `@packages/api/src/services/federation.ts`:
- Around line 1694-1699: The resolver resolveAgentProvider must use
Effect.Match.exhaustive to perform exhaustive pattern matching on the raw
provider string instead of the current ternary; update the function to compute
raw from subscription?.agentProvider ||
process.env["DOCKER_GIT_EXCHANGE_AGENT_PROVIDER"] and then call Match.exhaustive
with cases for "claude", "opencode", "grok", "custom", and "codex" (mapping each
to the corresponding AgentProvider) and an explicit default branch that returns
"codex" so all union values are handled; ensure you import Effect.Match and keep
the function signature types (FollowSubscription, AgentProvider) unchanged.

In `@packages/api/src/services/project-auth.ts`:
- Around line 173-197: Add a TSDoc block to the hasApiKeyInEnvFile function that
explains its purpose (checks whether a non-empty env variable named by the `key`
exists in a file), documents parameters `fs: FileSystem.FileSystem`,
`envFilePath: string`, and `key: string`, and states the return type
`Effect.Effect<boolean, PlatformError>` along with behavior on missing files or
read errors (returns false or uses provided Effect error handling). Mention
examples of expected env line formats (e.g., KEY=value, KEY="value") and note
that quotes are stripped and whitespace trimmed so only non-empty values return
true. Ensure the TSDoc appears immediately above the hasApiKeyInEnvFile
declaration.

In `@packages/app/src/docker-git/menu-auth.ts`:
- Around line 89-107: Replace the boolean OR chain used to compute suspendTui
inside submitAuthPrompt with an exhaustive pattern match over view.flow (use
Effect.Match.exhaustive or Match.exhaustive per coding guidelines) so all union
cases are handled; update the suspendTui argument passed to runAuthPromptEffect
(inside submitAuthPrompt) to be the result of that exhaustive match, and ensure
the match returns a boolean for each flow variant so future OAuth flows will
cause a compile-time failure if not handled.

In `@packages/app/src/docker-git/menu-project-auth.ts`:
- Around line 132-138: Replace the manual if-chain checking action
(ProjectGithubDisconnect | ProjectGitDisconnect | ProjectClaudeDisconnect |
ProjectGeminiDisconnect | ProjectGrokDisconnect) with an exhaustive pattern
match using Match.value(action).pipe(..., Match.exhaustive) to guarantee
compile-time coverage of the ProjectAuthMenuAction union; follow the same
pattern used in projectAuthSuccessMessage
(Match.value(...).pipe(Match.when(...), Match.exhaustive)), creating Match.when
clauses for each connect/disconnect branch and delegating to
startProjectAuthPrompt or the appropriate disconnect handling so any new union
variant will force a compile-time handling decision rather than silently falling
through.

In `@packages/app/src/lib/core/templates-entrypoint/rtk.ts`:
- Around line 9-44: The FORMAT THEOREM claims RTK configures "grok" but RTK has
no --grok flag, so update renderEntrypointRtkConfig to remove grok references:
change the FORMAT THEOREM token list to configured(codex, claude, gemini,
opencode) and delete "/home/__SSH_USER__/.grok" from the mkdir and chown paths
in the template body (and any related log text), leaving the four actual
docker_git_rtk_init_as_user invocations unchanged; this preserves the invariant
without adding unsupported RTK behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2789038d-8dd6-4ae0-aa69-a06d1d9b5989

📥 Commits

Reviewing files that changed from the base of the PR and between da15456 and b6cb6bf.

📒 Files selected for processing (106)
  • packages/api/src/api/contracts.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/api/src/http.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/services/auth-menu.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/services/container-tasks-core.ts
  • packages/api/src/services/federation.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/src/services/project-prompts.ts
  • packages/api/src/services/project-skills.ts
  • packages/api/src/services/projects.ts
  • packages/api/src/ui.ts
  • packages/api/tests/agents.test.ts
  • packages/app/src/docker-git/api-auth-codec.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/app/src/docker-git/cli/parser-apply.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/docker-git/cli/parser-options.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/docker-git/frontend-lib/core/auto-agent-flags.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts
  • packages/app/src/docker-git/frontend-lib/core/command-builders.ts
  • packages/app/src/docker-git/frontend-lib/core/command-options.ts
  • packages/app/src/docker-git/frontend-lib/core/domain.ts
  • packages/app/src/docker-git/frontend-lib/core/template-defaults.ts
  • packages/app/src/docker-git/menu-auth-effects.ts
  • packages/app/src/docker-git/menu-auth-shared.ts
  • packages/app/src/docker-git/menu-auth-snapshot-builder.ts
  • packages/app/src/docker-git/menu-auth.ts
  • packages/app/src/docker-git/menu-project-auth-shared.ts
  • packages/app/src/docker-git/menu-project-auth.ts
  • packages/app/src/docker-git/menu-render-auth.ts
  • packages/app/src/docker-git/menu-render-project-auth.ts
  • packages/app/src/docker-git/menu-types.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/app/src/lib/core/auto-agent-flags.ts
  • packages/app/src/lib/core/command-builders-template.ts
  • packages/app/src/lib/core/command-builders.ts
  • packages/app/src/lib/core/command-options.ts
  • packages/app/src/lib/core/domain.ts
  • packages/app/src/lib/core/template-defaults.ts
  • packages/app/src/lib/core/templates-entrypoint.ts
  • packages/app/src/lib/core/templates-entrypoint/agent.ts
  • packages/app/src/lib/core/templates-entrypoint/base.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/core/templates-entrypoint/project-rules.ts
  • packages/app/src/lib/core/templates-entrypoint/rtk.ts
  • packages/app/src/lib/core/templates/docker-compose.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/shell/config.ts
  • packages/app/src/lib/shell/docker-daemon-access.ts
  • packages/app/src/lib/usecases/apply-overrides.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth.ts
  • packages/app/src/web/action-prompt.ts
  • packages/app/src/web/actions-auth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api-prompts-schema.ts
  • packages/app/src/web/api-schema.ts
  • packages/app/src/web/api-skills-schema.ts
  • packages/app/src/web/api-skills.ts
  • packages/app/src/web/api-types.ts
  • packages/app/src/web/api.ts
  • packages/app/src/web/panel-auth.tsx
  • packages/app/src/web/panel-project-auth.tsx
  • packages/app/src/web/panel-project-prompts.tsx
  • packages/app/src/web/panel-project-skills.tsx
  • packages/app/tests/docker-git/actions-github-oauth.test.ts
  • packages/app/tests/docker-git/parser-auth.test.ts
  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/core/auto-agent-flags.ts
  • packages/lib/src/core/command-builders-template.ts
  • packages/lib/src/core/command-builders.ts
  • packages/lib/src/core/command-options.ts
  • packages/lib/src/core/domain.ts
  • packages/lib/src/core/template-defaults.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates-entrypoint/agent.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/project-rules.ts
  • packages/lib/src/core/templates-entrypoint/rtk.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/shell/config.ts
  • packages/lib/src/shell/docker-daemon-access.ts
  • packages/lib/src/usecases/apply-overrides.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/lib/src/usecases/auth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts

Comment thread packages/api/src/auth-terminal-runner.ts Outdated
Comment thread packages/api/src/services/auth-terminal-sessions.ts Outdated
Comment on lines +28 to +71
const buildTemplateConfigBase = (
input: Pick<BuildTemplateConfigInput, "repo" | "names" | "paths">
): Pick<
CreateCommand["config"],
| "containerName"
| "serviceName"
| "sshUser"
| "sshPort"
| "repoUrl"
| "repoRef"
| "targetDir"
| "volumeName"
| "dockerGitPath"
| "authorizedKeysPath"
| "envGlobalPath"
| "envProjectPath"
| "codexAuthPath"
| "codexSharedAuthPath"
| "codexHome"
| "geminiAuthPath"
| "geminiHome"
| "grokAuthPath"
| "grokHome"
> => ({
containerName: input.names.containerName,
serviceName: input.names.serviceName,
sshUser: input.repo.sshUser,
sshPort: input.repo.sshPort,
repoUrl: input.repo.repoUrl,
repoRef: input.repo.repoRef,
targetDir: input.repo.targetDir,
volumeName: input.names.volumeName,
dockerGitPath: input.paths.dockerGitPath,
authorizedKeysPath: input.paths.authorizedKeysPath,
envGlobalPath: input.paths.envGlobalPath,
envProjectPath: input.paths.envProjectPath,
codexAuthPath: input.paths.codexAuthPath,
codexSharedAuthPath: input.paths.codexSharedAuthPath,
codexHome: input.paths.codexHome,
geminiAuthPath: input.paths.geminiAuthPath,
geminiHome: input.paths.geminiHome,
grokAuthPath: input.paths.grokAuthPath,
grokHome: input.paths.grokHome
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавить обязательную документацию для CORE-функции.

Функция buildTemplateConfigBase является чистой функцией CORE-слоя и должна содержать полную TSDoc-документацию и функциональные комментарии. Согласно руководствам по кодированию, все CORE-функции должны включать:

  • TSDoc: @pure, @effect, @invariant, @precondition, @postcondition, @complexity
  • Функциональные комментарии: CHANGE, WHY, QUOTE(ТЗ) или n/a, REF, SOURCE или n/a, FORMAT THEOREM, PURITY, INVARIANT, COMPLEXITY
📝 Предлагаемый шаблон документации
+// CHANGE: extract base template config builder from repo/names/paths inputs
+// WHY: centralize config derivation logic for reuse across command builders
+// QUOTE(ТЗ): n/a
+// REF: PR-305-grok-auth-support
+// SOURCE: n/a
+// FORMAT THEOREM: ∀input: buildTemplateConfigBase(input) -> Pick<CreateCommand["config"], ...>
+// PURITY: CORE
+// INVARIANT: output config fields are derived deterministically from input
+// COMPLEXITY: O(1)/O(1)
+/**
+ * Builds the base template configuration from repository, naming, and path inputs.
+ *
+ * `@param` input - Repository basics, naming config, and path config.
+ * `@returns` Subset of CreateCommand config containing core fields.
+ * `@pure` true
+ * `@effect` none; CORE pure function.
+ * `@invariant` all output fields are deterministically derived from input.
+ * `@precondition` input.names and input.paths contain valid non-empty strings.
+ * `@postcondition` returned config includes all auth paths (codex/gemini/grok).
+ * `@complexity` O(1) time / O(1) space.
+ */
 const buildTemplateConfigBase = (

Согласно руководствам по кодированию: «Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)».

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`
around lines 28 - 71, Add full TSDoc and functional comments to the CORE pure
function buildTemplateConfigBase: include `@pure` (true/false), `@effect` (required
services or "none"), `@invariant` (any mathematical invariants), `@precondition`
(valid shape/constraints of input Pick<BuildTemplateConfigInput,...>),
`@postcondition` (returned object matches CreateCommand["config"] subset), and
`@complexity` (time and space). Also add the functional comment block with CHANGE,
WHY, QUOTE (or n/a), REF, SOURCE (or n/a), FORMAT THEOREM, PURITY, INVARIANT,
COMPLEXITY describing intent, rationale, references and guarantees for
buildTemplateConfigBase and reference the function name and the exact fields it
maps (containerName, serviceName, sshUser, sshPort, repoUrl, repoRef, targetDir,
volumeName, dockerGitPath, authorizedKeysPath, envGlobalPath, envProjectPath,
codexAuthPath, codexSharedAuthPath, codexHome, geminiAuthPath, geminiHome,
grokAuthPath, grokHome) to make clear mapping and postconditions.

Comment on lines +73 to +93
export const buildTemplateConfig = (input: BuildTemplateConfigInput): CreateCommand["config"] => ({
...buildTemplateConfigBase(input),
gitTokenLabel: input.gitTokenLabel,
skipGithubAuth: input.skipGithubAuth,
codexAuthLabel: input.codexAuthLabel,
claudeAuthLabel: input.claudeAuthLabel,
geminiAuthLabel: input.geminiAuthLabel,
grokAuthLabel: input.grokAuthLabel,
cpuLimit: input.cpuLimit,
ramLimit: input.ramLimit,
playwrightCpuLimit: input.playwrightCpuLimit,
playwrightRamLimit: input.playwrightRamLimit,
gpu: input.gpu,
dockerNetworkMode: input.dockerNetworkMode,
dockerSharedNetworkName: input.dockerSharedNetworkName,
enableMcpPlaywright: input.enableMcpPlaywright,
bunVersion: defaultTemplateConfig.bunVersion,
agentMode: input.agentMode,
agentAuto: input.agentAuto,
clonedOnHostname: input.clonedOnHostname
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавить обязательную документацию для экспортируемой CORE-функции.

Экспортируемая функция buildTemplateConfig должна содержать полную TSDoc и функциональные комментарии согласно руководствам.

📝 Предлагаемый шаблон документации
+// CHANGE: build complete template config from all input parameters
+// WHY: provide single source of truth for CreateCommand config construction
+// QUOTE(ТЗ): n/a
+// REF: PR-305-grok-auth-support
+// SOURCE: n/a
+// FORMAT THEOREM: ∀input: buildTemplateConfig(input) -> CreateCommand["config"]
+// PURITY: CORE
+// INVARIANT: output combines base config with resource limits, auth labels, and agent settings
+// COMPLEXITY: O(1)/O(1)
+/**
+ * Builds the complete template configuration from all input parameters.
+ *
+ * `@param` input - Complete build template configuration input.
+ * `@returns` Full CreateCommand configuration object.
+ * `@pure` true
+ * `@export`
+ * `@effect` none; CORE pure function.
+ * `@invariant` combines base config with all optional override fields.
+ * `@precondition` input satisfies BuildTemplateConfigInput type constraints.
+ * `@postcondition` returned config is valid CreateCommand["config"].
+ * `@complexity` O(1) time / O(1) space.
+ */
 export const buildTemplateConfig = (input: BuildTemplateConfigInput): CreateCommand["config"] => ({

Согласно руководствам по кодированию: «TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation».

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/frontend-lib/core/command-builders-template.ts`
around lines 73 - 93, The exported CORE function buildTemplateConfig lacks the
required comprehensive TSDoc; add a full TSDoc block immediately above the
exported function buildTemplateConfig describing the function purpose, each
parameter in BuildTemplateConfigInput (`@param`), the return type
CreateCommand["config"] (`@returns`), and include the required tags: `@pure`,
`@effect` (list any external deps such as buildTemplateConfigBase and
defaultTemplateConfig), `@invariant` (describe any invariants about returned
config), `@precondition` (validations on input fields like cpuLimit/ramLimit/gpu),
`@postcondition` (what properties will always be present in the returned config),
and `@complexity` (Big-O for any significant work); ensure references to internal
symbols buildTemplateConfigBase and defaultTemplateConfig are mentioned in the
text so readers can locate dependencies.

_tag: "InvalidOption",
option: "--auto",
reason: "expected one of: claude, codex"
reason: "expected one of: claude, codex, gemini, grok"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Синхронизируйте текст ошибки с фактической поддержкой значения auto.

requested === "auto" принимается как корректный режим, но в сообщении об ошибке это значение отсутствует.

💡 Предлагаемая правка
-    reason: "expected one of: claude, codex, gemini, grok"
+    reason: "expected one of: auto, claude, codex, gemini, grok"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/auto-agent-flags.ts` at line 23, Update the error
string that sets the `reason` (currently "expected one of: claude, codex,
gemini, grok") to include "auto" so it matches the accepted mode (`requested ===
"auto"`); ensure the `reason` value lists all supported modes including "auto"
and stays synchronized with any validation logic that references `requested`.

Comment thread packages/lib/src/usecases/auth-grok-oauth.ts
Comment thread packages/lib/src/usecases/auth-grok.ts Outdated
Comment on lines +50 to +62
export const authGrokLoginCli = (
_command: AuthGrokLoginCommand
): Effect.Effect<void, PlatformError | CommandFailedError, GrokRuntime> =>
Effect.gen(function*(_) {
yield* _(Effect.log("Grok CLI supports two authentication methods:"))
yield* _(Effect.log(""))
yield* _(Effect.log("1. API Key:"))
yield* _(Effect.log(" - Use: docker-git menu -> Auth profiles -> Grok CLI: set API key"))
yield* _(Effect.log(""))
yield* _(Effect.log("2. OAuth/browser login:"))
yield* _(Effect.log(" - Use: docker-git menu -> Auth profiles -> Grok CLI: login via OAuth"))
yield* _(Effect.log(" - Follow the Grok CLI prompts and paste the callback URL when requested"))
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Неиспользуемый параметр _command.

Параметр _command: AuthGrokLoginCommand помечен как неиспользуемый (префикс _), но не используется в теле функции. Если этот параметр необходим для соответствия интерфейсу или будет использован в будущем, оставьте как есть. В противном случае удалите его из сигнатуры.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok.ts` around lines 50 - 62, Параметр
_command в сигнатуре функции authGrokLoginCli не используется; либо удалите его
из сигнатуры (заменив экспорт на authGrokLoginCli(): Effect.Effect<...>) либо
начните явно использовать его внутри Effect.gen (например передав необходимые
поля в логи/логику) to satisfy the interface; обновите все вызовы/auth
signatures accordingly so they match the new signature or continue accepting the
parameter if required for interface compatibility.

Comment thread packages/lib/src/usecases/auth-grok.ts Outdated
Comment on lines +10 to +23
const withTempDir = <A, E, R>(
use: (tempDir: string) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R | FileSystem.FileSystem> =>
Effect.scoped(
Effect.gen(function*(_) {
const fs = yield* _(FileSystem.FileSystem)
const tempDir = yield* _(
fs.makeTempDirectoryScoped({
prefix: "docker-git-auth-grok-"
})
)
return yield* _(use(tempDir))
})
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Добавить TSDoc для тестового хелпера.

Хелпер withTempDir использует Effect.scoped для управления ресурсами, что является важным паттерном. Добавьте краткую TSDoc для документирования его назначения и использования.

📝 Предлагаемая документация
+/**
+ * Runs an effect with a scoped temporary directory that is automatically cleaned up.
+ *
+ * `@param` use - Effect to run with the temporary directory path.
+ * `@returns` Scoped effect with FileSystem dependency.
+ * `@pure` true
+ * `@effect` FileSystem
+ */
 const withTempDir = <A, E, R>(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/tests/usecases/auth-grok.test.ts` around lines 10 - 23, Добавьте
краткую TSDoc над helper-функцией withTempDir, объясняющую её назначение
(создаёт временную директорию для теста и передаёт её в callback), описывающую
использование Effect.scoped для управления жизненным циклом ресурса,
перечисляющую параметр use (callback, получающий tempDir: string) и возвращаемое
значение (Effect, который может содержать результат теста или
FileSystem.FileSystem), и упомяните префикс временной директории; ссылаясь на
сimbols withTempDir, Effect.scoped и FileSystem.FileSystem, чтобы облегчить
поиск места вставки документации.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/lib/src/usecases/agent-auto-select.ts (1)

1-181: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Дублирование кода между packages/lib и packages/app.

Файл идентичен packages/app/src/lib/usecases/agent-auto-select.ts. Все замечания из review того файла применимы и здесь:

  • Отсутствует TSDoc-документация для hasGrokAuth, availableAgentModes, pickRandomAutoAgentMode
  • Отсутствуют функциональные комментарии (CHANGE, WHY, PURITY, EFFECT, INVARIANT, COMPLEXITY)
  • Одноэлементные массивы-константы можно упростить

Дополнительно: дублирование кода нарушает DRY-принцип и усложняет поддержку. Рассмотрите:

  1. Если packages/lib — это shared library, то packages/app должен импортировать из неё
  2. Если это монорепозиторий, используйте workspace references для переиспользования кода
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/agent-auto-select.ts` around lines 1 - 181, This
file duplicates logic from packages/app; remove duplication by centralizing the
agent selection code into the shared lib and have packages/app import it (or
create a single shared module/workspace reference) and, in this file, replace
the duplicated implementation with an import; while consolidating, add TSDoc and
the repository's functional comment blocks
(CHANGE/WHY/PURITY/EFFECT/INVARIANT/COMPLEXITY) for the functions hasGrokAuth,
availableAgentModes, and pickRandomAutoAgentMode, and simplify the
single-element constants claudeMode, codexMode, grokMode to plain string
literals where used (or export simple string constants) to reduce unnecessary
arrays; update resolveAvailableAgentAuth, resolveExplicitAutoAgentMode, and
pickRandomAutoAgentMode call sites to use the centralized implementation and
ensure exports/signatures match between packages.
packages/lib/tests/usecases/agent-auto-select.test.ts (1)

119-219: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Тестовое покрытие Grok добавлено, но отсутствуют property-based тесты.

Новые тесты для Grok адресуют замечание из previous review comment о недостаточном покрытии. Однако согласно coding guidelines, требуется использовать property-based testing с fast-check для проверки математических инвариантов.

Примеры инвариантов для property-based тестов:

  1. Детерминированность при одном доступном режиме: ∀available: |availableModes| = 1 ⇒ result = availableModes[0]
  2. Принадлежность результата: ∀available: result ∈ availableAgentModes(available)
  3. Идемпотентность explicit mode: ∀mode ∈ {claude, codex, grok}: agentMode=mode ∧ authAvailable(mode) ⇒ result=mode
  4. Fail when unavailable: ∀mode: agentMode=mode ∧ ¬authAvailable(mode) ⇒ Effect.fail(InvalidOption)
Пример property-based теста с fast-check
import * as fc from "fast-check"

it.effect("property: resolved mode always belongs to available modes", () =>
  Effect.gen(function*(_) {
    const property = fc.property(
      fc.record({
        claudeAvailable: fc.boolean(),
        codexAvailable: fc.boolean(),
        grokAvailable: fc.boolean()
      }).filter(avail => avail.claudeAvailable || avail.codexAvailable || avail.grokAvailable),
      (available) => {
        // Setup auth files based on available flags
        // Call resolveAutoAgentMode
        // Assert result ∈ availableAgentModes(available)
      }
    )
    fc.assert(property)
  })
)

As per coding guidelines **/*.test.{ts,tsx}: "Implement property-based testing using fast-check for mathematical properties and invariants."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/tests/usecases/agent-auto-select.test.ts` around lines 119 -
219, The new Grok unit tests lack property-based tests as required; add
fast-check property tests in
packages/lib/tests/usecases/agent-auto-select.test.ts that exercise
resolveAutoAgentMode across randomized availability combinations: import fc from
"fast-check" and add it.effect cases that generate boolean flags
(claudeAvailable, codexAvailable, grokAvailable) filtered to at least one true,
create auth files in the temp dir based on those flags (using
FileSystem.FileSystem and Path.Path as in existing tests), call
resolveAutoAgentMode(config) and assert the invariants: (1) if exactly one mode
is available the result equals that mode, (2) result is one of the available
modes, (3) when agentMode is explicitly set to an available mode result equals
that explicit mode, and (4) when explicit mode is set but its auth is missing
the effect fails with InvalidOption; use fc.assert to run the property and wrap
inside the existing withTempDir/Effect.gen pattern.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/docker-git/cli/usage.ts`:
- Line 79: The help text advertises Gemini but the auto-selection logic and
types lack Gemini support; update AvailableAgentAuth to include geminiAvailable,
extend availableAgentModes (in packages/lib/src/usecases/agent-auto-select.ts,
function availableAgentModes) to check available.geminiAvailable and include
AgentMode.Gemini in the returned modes when present, update the error message
that currently says "no Claude, Codex or Grok auth found" to mention Gemini, and
add/adjust unit tests to cover the Gemini path; alternatively, if you prefer to
postpone Gemini, remove "gemini" from the --auto help text and AgentMode enum
usages so the doc and logic remain consistent.

In `@packages/app/src/lib/usecases/agent-auto-select.ts`:
- Around line 137-141: Add comprehensive TSDoc to the pure CORE helper
availableAgentModes: mark it with `@pure` true, add functional comments describing
PURITY (CORE) and `@effect` (none/required services = none), specify `@invariant`
such as "∀available: |result| ≤ 3 ∧ result ⊆ {claude, codex, grok}", document
`@precondition` (none) and `@postcondition` (returns array of AgentMode containing
only enabled modes), and state `@complexity` as "time O(1), space O(1)". Place
this TSDoc immediately above the availableAgentModes declaration so tools and
reviewers can pick it up.
- Around line 143-153: Add comprehensive TSDoc to the pickRandomAutoAgentMode
function: document `@pure` false (uses process.hrtime.bigint()), `@effect`
describing the Effect<AgentMode, ParseError> and any required services,
`@invariant` stating the result ∈ availableAgentModes(available), `@precondition`
that availableAgentModes(available) is non-empty, `@postcondition` that the
returned AgentMode is one of the available modes or an error, and `@complexity`
O(n) where n = number of modes; reference the helper availableAgentModes and the
non-deterministic selection via process.hrtime.bigint() when describing WHY and
EFFECT.
- Around line 53-60: The new function hasGrokAuth lacks the required TSDoc; add
a comprehensive TSDoc block above hasGrokAuth that documents `@pure` false,
`@effect` FileSystem (since it uses FileSystem.FileSystem and returns an Effect),
`@precondition` (rootPath is a valid path string and label may be undefined),
`@postcondition` (returns true if valid Grok credentials are found at
normalizeAccountLabel(label ?? null, "default") within rootPath), `@complexity`
(time and space complexity of hasGrokCredentials call), and include the
functional comments PURITY (SHELL), EFFECT (Effect<boolean, PlatformError,
FileSystem>), and INVARIANT describing the relationship between normalized label
and lookup path; reference the helper functions normalizeAccountLabel and
hasGrokCredentials in the comment for clarity.
- Around line 24-26: The three constants claudeMode, codexMode and grokMode are
defined as one-element ReadonlyArray<AgentMode>, which is unnecessary because
availableAgentModes later spreads them; change them to use simple string
literals or single AgentMode values and insert those directly into
availableAgentModes (e.g., replace the one-item arrays with 'claude', 'codex',
'grok' or define each as const claudeMode: AgentMode = 'claude') to remove the
extra array layer and keep type-safety.

In `@packages/lib/tests/usecases/agent-auto-select.test.ts`:
- Around line 42-45: The test suite adds geminiAuthPath and geminiHome to
makeConfig but no Gemini test-cases exist; either add three tests mirroring
Grok's coverage (in packages/lib/tests/usecases/agent-auto-select.test.ts) named
it.effect("chooses Gemini when only Gemini auth exists", ...), it.effect("keeps
explicit Gemini mode when Gemini auth exists", ...), and it.effect("fails
explicit Gemini mode when Gemini auth is missing", ...) exercising the same
setup/teardowns and assertions used for Grok, or if Gemini is out of scope for
this PR, remove or comment out geminiAuthPath/geminiHome from makeConfig and add
a "// TODO: Gemini tests" comment to explain why they are omitted.

---

Outside diff comments:
In `@packages/lib/src/usecases/agent-auto-select.ts`:
- Around line 1-181: This file duplicates logic from packages/app; remove
duplication by centralizing the agent selection code into the shared lib and
have packages/app import it (or create a single shared module/workspace
reference) and, in this file, replace the duplicated implementation with an
import; while consolidating, add TSDoc and the repository's functional comment
blocks (CHANGE/WHY/PURITY/EFFECT/INVARIANT/COMPLEXITY) for the functions
hasGrokAuth, availableAgentModes, and pickRandomAutoAgentMode, and simplify the
single-element constants claudeMode, codexMode, grokMode to plain string
literals where used (or export simple string constants) to reduce unnecessary
arrays; update resolveAvailableAgentAuth, resolveExplicitAutoAgentMode, and
pickRandomAutoAgentMode call sites to use the centralized implementation and
ensure exports/signatures match between packages.

In `@packages/lib/tests/usecases/agent-auto-select.test.ts`:
- Around line 119-219: The new Grok unit tests lack property-based tests as
required; add fast-check property tests in
packages/lib/tests/usecases/agent-auto-select.test.ts that exercise
resolveAutoAgentMode across randomized availability combinations: import fc from
"fast-check" and add it.effect cases that generate boolean flags
(claudeAvailable, codexAvailable, grokAvailable) filtered to at least one true,
create auth files in the temp dir based on those flags (using
FileSystem.FileSystem and Path.Path as in existing tests), call
resolveAutoAgentMode(config) and assert the invariants: (1) if exactly one mode
is available the result equals that mode, (2) result is one of the available
modes, (3) when agentMode is explicitly set to an available mode result equals
that explicit mode, and (4) when explicit mode is set but its auth is missing
the effect fails with InvalidOption; use fc.assert to run the property and wrap
inside the existing withTempDir/Effect.gen pattern.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 24d7c545-cc31-4d9c-8519-8643b38d69a3

📥 Commits

Reviewing files that changed from the base of the PR and between b6cb6bf and 61978c7.

📒 Files selected for processing (4)
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/lib/usecases/agent-auto-select.ts
  • packages/lib/tests/usecases/agent-auto-select.test.ts
  • packages/lib/src/usecases/agent-auto-select.ts
  • packages/app/src/docker-git/cli/usage.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/agent-auto-select.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/agent-auto-select.test.ts
🔇 Additional comments (1)
packages/app/src/lib/usecases/agent-auto-select.ts (1)

129-133: LGTM!

Comment on lines +24 to +26
const claudeMode: ReadonlyArray<AgentMode> = ["claude"]
const codexMode: ReadonlyArray<AgentMode> = ["codex"]
const grokMode: ReadonlyArray<AgentMode> = ["grok"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Рассмотрите использование литералов вместо одноэлементных массивов.

Константы claudeMode, codexMode, grokMode определены как одноэлементные ReadonlyArray<AgentMode>. Это добавляет дополнительный уровень абстракции без очевидной пользы. В availableAgentModes их всё равно приходится распаковывать через spread.

Более прямолинейное решение — использовать string literals напрямую в массиве или, если массивы нужны для типобезопасности, добавить комментарий, объясняющий WHY.

♻️ Возможное упрощение
-const claudeMode: ReadonlyArray<AgentMode> = ["claude"]
-const codexMode: ReadonlyArray<AgentMode> = ["codex"]
-const grokMode: ReadonlyArray<AgentMode> = ["grok"]
-
 const availableAgentModes = (available: AvailableAgentAuth): ReadonlyArray<AgentMode> => [
-  ...(available.claudeAvailable ? claudeMode : []),
-  ...(available.codexAvailable ? codexMode : []),
-  ...(available.grokAvailable ? grokMode : [])
+  ...(available.claudeAvailable ? ["claude" as const] : []),
+  ...(available.codexAvailable ? ["codex" as const] : []),
+  ...(available.grokAvailable ? ["grok" as const] : [])
 ]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 24 - 26, The
three constants claudeMode, codexMode and grokMode are defined as one-element
ReadonlyArray<AgentMode>, which is unnecessary because availableAgentModes later
spreads them; change them to use simple string literals or single AgentMode
values and insert those directly into availableAgentModes (e.g., replace the
one-item arrays with 'claude', 'codex', 'grok' or define each as const
claudeMode: AgentMode = 'claude') to remove the extra array layer and keep
type-safety.

Comment on lines +53 to +60
const hasGrokAuth = (
fs: FileSystem.FileSystem,
rootPath: string,
label: string | undefined
): Effect.Effect<boolean, PlatformError> => {
const normalized = normalizeAccountLabel(label ?? null, "default")
return hasGrokCredentials(fs, `${rootPath}/${normalized}`)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Отсутствует обязательная TSDoc-документация для новой функции.

Согласно coding guidelines, все функции должны содержать comprehensive TSDoc с указанием:

  • @pure (false, т.к. FileSystem effect)
  • @effect (FileSystem dependency)
  • @precondition (например, rootPath должен быть валидным путём)
  • @postcondition (возвращает true если найдены валидные Grok credentials)
  • @complexity (временная и пространственная)

Также требуются функциональные комментарии: PURITY (SHELL), EFFECT (Effect<boolean, PlatformError, FileSystem>), INVARIANT.

As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 53 - 60, The
new function hasGrokAuth lacks the required TSDoc; add a comprehensive TSDoc
block above hasGrokAuth that documents `@pure` false, `@effect` FileSystem (since it
uses FileSystem.FileSystem and returns an Effect), `@precondition` (rootPath is a
valid path string and label may be undefined), `@postcondition` (returns true if
valid Grok credentials are found at normalizeAccountLabel(label ?? null,
"default") within rootPath), `@complexity` (time and space complexity of
hasGrokCredentials call), and include the functional comments PURITY (SHELL),
EFFECT (Effect<boolean, PlatformError, FileSystem>), and INVARIANT describing
the relationship between normalized label and lookup path; reference the helper
functions normalizeAccountLabel and hasGrokCredentials in the comment for
clarity.

Comment on lines +137 to +141
const availableAgentModes = (available: AvailableAgentAuth): ReadonlyArray<AgentMode> => [
...(available.claudeAvailable ? claudeMode : []),
...(available.codexAvailable ? codexMode : []),
...(available.grokAvailable ? grokMode : [])
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Отсутствует обязательная TSDoc-документация.

Функция availableAgentModes является чистой (CORE layer) и должна содержать:

  • @pure true
  • @invariant (например: "∀available: |result| ≤ 3 ∧ result ⊆ {claude, codex, grok}")
  • @complexity O(1) время, O(1) пространство (возвращает массив фиксированного размера ≤3)

Также требуются функциональные комментарии: PURITY (CORE), INVARIANT, COMPLEXITY.

As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 137 - 141,
Add comprehensive TSDoc to the pure CORE helper availableAgentModes: mark it
with `@pure` true, add functional comments describing PURITY (CORE) and `@effect`
(none/required services = none), specify `@invariant` such as "∀available:
|result| ≤ 3 ∧ result ⊆ {claude, codex, grok}", document `@precondition` (none)
and `@postcondition` (returns array of AgentMode containing only enabled modes),
and state `@complexity` as "time O(1), space O(1)". Place this TSDoc immediately
above the availableAgentModes declaration so tools and reviewers can pick it up.

Comment on lines +143 to 153
const pickRandomAutoAgentMode = (available: AvailableAgentAuth): Effect.Effect<AgentMode, ParseError> => {
const modes = availableAgentModes(available)
const firstMode = modes[0]
if (firstMode === undefined) {
return Effect.fail(autoOptionError("no Claude, Codex or Grok auth found"))
}
if (!available.claudeAvailable && available.codexAvailable) {
return Effect.succeed("codex")
if (modes.length === 1) {
return Effect.succeed(firstMode)
}
return Effect.sync(() => (process.hrtime.bigint() % 2n === 0n ? "claude" : "codex"))
return Effect.sync(() => modes[Number(process.hrtime.bigint() % BigInt(modes.length))] ?? firstMode)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Отсутствует обязательная TSDoc-документация для критической логики выбора.

Функция pickRandomAutoAgentMode реализует случайный выбор агента из доступных и требует полную документацию:

  • @pure false (использует process.hrtime.bigint())
  • @effect требует описание побочного эффекта (non-deterministic random selection)
  • @invariant (например: "result ∈ availableAgentModes(available)")
  • @precondition должны существовать доступные режимы для выбора
  • @postcondition возвращает один из доступных режимов или ошибку
  • @complexity O(n) где n = количество доступных режимов

Функциональные комментарии должны включать:

  • PURITY (SHELL)
  • EFFECT (Effect<AgentMode, ParseError>)
  • INVARIANT (результат принадлежит множеству доступных режимов)
  • WHY (почему используется process.hrtime вместо Math.random - детерминизм тестирования?)

As per coding guidelines **/*.{ts,tsx}: "Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/agent-auto-select.ts` around lines 143 - 153,
Add comprehensive TSDoc to the pickRandomAutoAgentMode function: document `@pure`
false (uses process.hrtime.bigint()), `@effect` describing the Effect<AgentMode,
ParseError> and any required services, `@invariant` stating the result ∈
availableAgentModes(available), `@precondition` that
availableAgentModes(available) is non-empty, `@postcondition` that the returned
AgentMode is one of the available modes or an error, and `@complexity` O(n) where
n = number of modes; reference the helper availableAgentModes and the
non-deterministic selection via process.hrtime.bigint() when describing WHY and
EFFECT.

Comment on lines +42 to +45
geminiAuthPath: path.join(root, ".orch/auth/gemini"),
geminiHome: "/home/dev/.gemini",
grokAuthPath: path.join(root, ".orch/auth/grok"),
grokHome: "/home/dev/.grok",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Поиск упоминаний Gemini в реализации (не только в тестах и usage)
rg -nP --type=ts -C2 'gemini|Gemini' --iglob '**/usecases/**' --iglob '!**/*.test.ts' --iglob '!**/usage.ts'

Repository: ProverCoderAI/docker-git

Length of output: 50380


🏁 Script executed:

# Посмотрим содержимое тестового файла, чтобы увидеть тест-кейсы
head -100 packages/lib/tests/usecases/agent-auto-select.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 3865


🏁 Script executed:

# Получим полный список тест-кейсов (строки с it.effect)
rg -n "it\.effect" packages/lib/tests/usecases/agent-auto-select.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 873


🏁 Script executed:

# Проверим, есть ли вообще упоминание Gemini в тестовом файле
rg -i "gemini" packages/lib/tests/usecases/agent-auto-select.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 159


Добавьте тест-кейсы для Gemini агента или удалите неиспользуемые поля конфига.

В makeConfig добавлены geminiAuthPath и geminiHome, но в файле тестов отсутствуют тест-кейсы для Gemini. Grok имеет полное покрытие (3 теста: выбор агента, явный режим, ошибка), а Gemini не протестирован, несмотря на то, что полностью реализован в production-коде.

Выберите один из подходов:

  1. Добавьте недостающие тест-кейсы для Gemini (аналогично Grok):

    • it.effect("chooses Gemini when only Gemini auth exists", ...)
    • it.effect("keeps explicit Gemini mode when Gemini auth exists", ...)
    • it.effect("fails explicit Gemini mode when Gemini auth is missing", ...)
  2. Или добавьте комментарий // TODO: Gemini tests и откомментируйте поля конфига, если Gemini не должен быть в scope этого PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/tests/usecases/agent-auto-select.test.ts` around lines 42 - 45,
The test suite adds geminiAuthPath and geminiHome to makeConfig but no Gemini
test-cases exist; either add three tests mirroring Grok's coverage (in
packages/lib/tests/usecases/agent-auto-select.test.ts) named it.effect("chooses
Gemini when only Gemini auth exists", ...), it.effect("keeps explicit Gemini
mode when Gemini auth exists", ...), and it.effect("fails explicit Gemini mode
when Gemini auth is missing", ...) exercising the same setup/teardowns and
assertions used for Grok, or if Gemini is out of scope for this PR, remove or
comment out geminiAuthPath/geminiHome from makeConfig and add a "// TODO: Gemini
tests" comment to explain why they are omitted.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 1-2: The file packages/app src lib core templates-entrypoint
grok.ts duplicates logic present in
packages/lib/src/core/templates-entrypoint/grok.ts; remove the duplicate by
extracting the shared code (including the TemplateConfig-related logic and any
exported helpers) into a single shared module or the lib package and have
packages/app re-export or import that module (e.g., export/import the same
symbols instead of re-defining them). Update the grok.ts in packages/app to
import TemplateConfig and any functions from the shared location (or re-export
from packages/lib) so only one source of truth remains and jscpd markers are no
longer needed.
- Around line 259-266: Экспортная функция renderEntrypointGrokConfig не имеет
TSDoc — добавьте подробный TSDoc над объявлением функции
renderEntrypointGrokConfig, описывающий назначение функции, параметры (config:
TemplateConfig) и возвращаемое значение (string), а также любые побочные эффекты
или примечания; используйте стиль и уровень детализации, согласованный с другими
файлами (например, packages/lib/src/core/templates-entrypoint/grok.ts), включая
пример использования при необходимости.

In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 258-265: Add a comprehensive TSDoc block to the exported function
renderEntrypointGrokConfig describing its purpose and behavior, and include the
required tags: `@pure`, `@effect` (describe side effects or "none"), `@invariant`,
`@precondition` (e.g., valid TemplateConfig), `@postcondition` (what string
structure is returned), and `@complexity` (time/space complexity). Place the
comment immediately above the renderEntrypointGrokConfig declaration and
reference the parameter config and returned string in the descriptions so that
consumers and linters get the full contract for this exported function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8b8093ce-8bc9-43dd-9c7b-3c14a8b15010

📥 Commits

Reviewing files that changed from the base of the PR and between 61978c7 and d4d0fe9.

📒 Files selected for processing (3)
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/templates.test.ts
🔇 Additional comments (6)
packages/lib/src/core/templates-entrypoint/grok.ts (4)

1-12: LGTM!

Also applies to: 122-126, 144-164, 165-170, 172-188, 253-257


13-121: LGTM!


127-143: LGTM!


189-252: LGTM!

packages/lib/tests/core/templates.test.ts (1)

30-30: LGTM!

Also applies to: 216-224, 419-463, 484-496, 498-526

packages/app/src/lib/core/templates-entrypoint/grok.ts (1)

3-258: LGTM!

Comment on lines +1 to +2
/* jscpd:ignore-start */
import type { TemplateConfig } from "../domain.js"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Дублирование кода между packages/lib и packages/app.

Файл полностью идентичен packages/lib/src/core/templates-entrypoint/grok.ts. Маркеры jscpd:ignore подавляют предупреждения, но любое исправление потребует синхронизации обоих файлов.

Рассмотрите возможность вынести общую логику в shared-пакет или re-export из lib, если архитектура это позволяет.

Also applies to: 267-267

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/templates-entrypoint/grok.ts` around lines 1 - 2,
The file packages/app src lib core templates-entrypoint grok.ts duplicates logic
present in packages/lib/src/core/templates-entrypoint/grok.ts; remove the
duplicate by extracting the shared code (including the TemplateConfig-related
logic and any exported helpers) into a single shared module or the lib package
and have packages/app re-export or import that module (e.g., export/import the
same symbols instead of re-defining them). Update the grok.ts in packages/app to
import TemplateConfig and any functions from the shared location (or re-export
from packages/lib) so only one source of truth remains and jscpd markers are no
longer needed.

Comment thread packages/app/src/lib/core/templates-entrypoint/grok.ts
Comment thread packages/lib/src/core/templates-entrypoint/grok.ts
@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 15, 2026

Working session summary

Готово: PR 305 обновлён и готов к ревью: #305

Что добавлено поверх основной Grok-поддержки:

  • Исправил CI-регрессию GROK_API_KEY: unbound variable в generated Grok entrypoint.
  • Добавил регрессионный тест, который проверяет, что bash defaults рендерятся как ${GROK_API_KEY:-}, без экранированного \${...}.
  • Запушил коммит d4d0fe9 fix(auth): tolerate missing grok api key in entrypoint.

Проверки:

  • Локально прошли bun run typecheck, bun run lint, bun run lint:effect, bun run test, bun run api:test.
  • GitHub checks на d4d0fe9 все зелёные, включая E2E (Clone auto-open SSH), где раньше падало.
  • gh pr checks 305 показывает pass по всем checks, включая CodeRabbit.
  • Working tree чистый.

SOURCE: n/a


This summary was automatically extracted from the AI working session output.

@skulidropek
Copy link
Copy Markdown
Member

Испраьв всё что написал rabbit coder

@konard
Copy link
Copy Markdown
Contributor Author

konard commented May 17, 2026

🚨 Solution Draft Failed

The automated solution draft encountered an error:

The solver stopped while continuing pull request #305.

Reason: Repository setup halted - fork divergence requires user decision

What you can do

  • If the fork's default branch can be overwritten safely, rerun with --allow-fork-divergence-resolution-using-force-push-with-lease to allow a guarded force-with-lease sync.
  • If the fork has commits you need to preserve, resolve the divergence manually, then rerun the solver.
  • If this requires elevated Hive Mind access, ask a Hive Mind administrator to handle the affected fork or repository.

Administrator-only CLI details, if any, are printed in the solver terminal log rather than in this GitHub comment.

🤖 Models used:

  • Tool: OpenAI Codex
  • Requested: gpt-5.5
  • Model: GPT-5.5 (gpt-5.5)
Click to expand failure log (33KB)
# Solve.mjs Log - 2026-05-17T13:17:40.868Z

[2026-05-17T13:17:40.869Z] [INFO] 📁 Log file: /home/box/solve-2026-05-17T13-17-40-867Z.log
[2026-05-17T13:17:40.869Z] [INFO]    (All output will be logged here)
[2026-05-17T13:17:41.579Z] [INFO] 
[2026-05-17T13:17:41.580Z] [INFO] 🚀 solve v1.72.0
[2026-05-17T13:17:41.581Z] [INFO] 🔧 Raw command executed:
[2026-05-17T13:17:41.581Z] [INFO]    /home/box/.nvm/versions/node/v20.20.2/bin/node /home/box/.bun/bin/solve https://github.com/ProverCoderAI/docker-git/pull/305 --think max --tool codex --attach-logs --verbose --no-tool-check --disable-report-issue --language en
[2026-05-17T13:17:41.583Z] [INFO] 
[2026-05-17T13:17:42.126Z] [INFO] 
[2026-05-17T13:17:42.127Z] [WARNING] ⚠️  SECURITY WARNING: --attach-logs is ENABLED
[2026-05-17T13:17:42.128Z] [INFO] 
[2026-05-17T13:17:42.128Z] [INFO]    This option will upload the complete solution draft log file to the Pull Request.
[2026-05-17T13:17:42.128Z] [INFO]    The log may contain sensitive information such as:
[2026-05-17T13:17:42.129Z] [INFO]    • API keys, tokens, or secrets
[2026-05-17T13:17:42.129Z] [INFO]    • File paths and directory structures
[2026-05-17T13:17:42.129Z] [INFO]    • Command outputs and error messages
[2026-05-17T13:17:42.129Z] [INFO]    • Internal system information
[2026-05-17T13:17:42.130Z] [INFO] 
[2026-05-17T13:17:42.130Z] [INFO]    ⚠️  DO NOT use this option with public repositories or if the log
[2026-05-17T13:17:42.130Z] [INFO]        might contain sensitive data that should not be shared publicly.
[2026-05-17T13:17:42.130Z] [INFO] 
[2026-05-17T13:17:42.131Z] [INFO]    Continuing in 5 seconds... (Press Ctrl+C to abort)
[2026-05-17T13:17:42.131Z] [INFO] 
[2026-05-17T13:17:42.131Z] [STDOUT] 
   Countdown: 5 seconds remaining...
[2026-05-17T13:17:43.133Z] [STDOUT] 
   Countdown: 4 seconds remaining...
[2026-05-17T13:17:44.134Z] [STDOUT] 
   Countdown: 3 seconds remaining...
[2026-05-17T13:17:45.135Z] [STDOUT] 
   Countdown: 2 seconds remaining...
[2026-05-17T13:17:46.136Z] [STDOUT] 
   Countdown: 1 seconds remaining...
[2026-05-17T13:17:47.136Z] [STDOUT] 
   Proceeding with log attachment enabled.                    
[2026-05-17T13:17:47.136Z] [INFO] 
[2026-05-17T13:17:47.176Z] [INFO] 💾 Disk space check: 13696MB available (2048MB required) ✅
[2026-05-17T13:17:47.178Z] [INFO] 🧠 Memory check: 10669MB available, swap: none, total: 10669MB (256MB required) ✅
[2026-05-17T13:17:47.195Z] [INFO] ⏩ Skipping tool connection validation (dry-run mode or skip-tool-connection-check enabled)
[2026-05-17T13:17:47.195Z] [INFO] ⏩ Skipping GitHub authentication check (dry-run mode or skip-tool-connection-check enabled)
[2026-05-17T13:17:47.196Z] [INFO] 📋 URL validation:
[2026-05-17T13:17:47.196Z] [INFO]    Input URL: https://github.com/ProverCoderAI/docker-git/pull/305
[2026-05-17T13:17:47.196Z] [INFO]    Is Issue URL: false
[2026-05-17T13:17:47.196Z] [INFO]    Is PR URL: true
[2026-05-17T13:17:47.197Z] [INFO] 🔍 --auto-accept-invite: Checking for pending invitation to ProverCoderAI/docker-git...
[2026-05-17T13:17:47.475Z] [INFO]    Found 1 total pending repo invitation(s)
[2026-05-17T13:17:47.476Z] [INFO]    No pending repository invitation found for ProverCoderAI/docker-git
[2026-05-17T13:17:47.847Z] [INFO]    Found 0 total pending org invitation(s)
[2026-05-17T13:17:47.847Z] [INFO]    No pending organization invitation found for ProverCoderAI
[2026-05-17T13:17:47.848Z] [INFO] ℹ️  --auto-accept-invite: No pending invitation found for ProverCoderAI/docker-git or organization ProverCoderAI
[2026-05-17T13:17:47.848Z] [INFO] 🔍 Checking repository access for auto-fork...
[2026-05-17T13:17:48.235Z] [STDOUT] {"admin":false,"maintain":false,"pull":true,"push":false,"triage":false}
[2026-05-17T13:17:48.599Z] [STDOUT] public
[2026-05-17T13:17:48.604Z] [INFO]    Repository visibility: public
[2026-05-17T13:17:48.605Z] [INFO] ✅ Auto-fork: No write access detected, enabling fork mode
[2026-05-17T13:17:48.605Z] [INFO] ✅ Repository access check: Skipped (fork mode enabled)
[2026-05-17T13:17:48.853Z] [STDOUT] ProverCoderAI
[2026-05-17T13:17:49.267Z] [STDOUT] ProverCoderAI/docker-git
[2026-05-17T13:17:49.571Z] [STDOUT] {"number":305,"state":"OPEN"}
[2026-05-17T13:17:49.942Z] [STDOUT] public
[2026-05-17T13:17:49.946Z] [INFO]    Repository visibility: public
[2026-05-17T13:17:49.946Z] [INFO]    Auto-cleanup default: false (repository is public)
[2026-05-17T13:17:49.947Z] [INFO] 🔄 Continue mode: Working with PR #305
[2026-05-17T13:17:49.947Z] [INFO]    Continue mode activated: PR URL provided directly
[2026-05-17T13:17:49.947Z] [INFO]    PR Number set to: 305
[2026-05-17T13:17:49.947Z] [INFO]    Will fetch PR details and linked issue
[2026-05-17T13:17:50.365Z] [STDOUT] {"body":"Fixes ProverCoderAI/docker-git#304\n\n## Summary\n- Adds Grok as a first-class auth provider across CLI parsing, API contracts, TUI/web auth menus, project auth snapshots, prompt/skill provider schemas, and `--auto grok` agent selection.\n- Adds Grok credential use cases for API-key login, OAuth/browser login through `grok login`, status, logout, `.docker-git/.orch/auth/grok/<label>` storage, and state auto-sync.\n- Extends generated project templates to install `grok-dev@latest`, configure `~/.grok`, disable sandbox by default, wire Playwright MCP, provide passwordless sudo, and support Grok project rules/system prompt hooks.\n- Guards generated Grok entrypoint shell against missing optional `GROK_API_KEY`/`XAI_API_KEY` under `set -u` by rendering real `${VAR:-}` bash defaults instead of escaped literals.\n- Keeps Docker daemon probing typed by mapping missing Docker CLI spawn failures to `DockerAccessError(DaemonUnavailable)` instead of leaking platform exceptions into API rendering tests.\n\n## Reproduction / Verification\n1. Before this change, `auth grok ...`, `--auto grok`, Grok provider schemas, and Grok template auth paths were absent.\n2. A CI regression reproduced the generated entrypoint failure as `/entrypoint.sh: line 2320: GROK_API_KEY: unbound variable` when no Grok API key was mounted.\n3. The reproducing coverage now checks Grok parser commands, Grok API-key credential materialization, template rendering, auto-agent selection, API agent command rendering, and unescaped Grok bash default expansion.\n\n## Mathematical Guarantees\n### Invariants\n- `forall label: authGrokLogin(label, key) -> exists .docker-git/.orch/auth/grok/normalize(label)/.api-key`\n- `forall project: grokAuthLabel(project) -> Grok credentials are mounted from the selected label only`\n- `forall Grok agent run: command includes sandbox disabled and Playwright MCP isolation enabled`\n- `forall generated Grok entrypoint: unset(GROK_API_KEY) -> no nounset failure during env refresh`\n- `forall credential status checks: no API key value is logged`\n\n### Preconditions\n- API-key login requires a non-empty key provided by the auth boundary.\n- OAuth login requires Docker availability because it executes `grok login` in the auth image.\n\n### Postconditions\n- Grok project templates contain `.grok/settings.json` with Playwright MCP and sandbox off.\n- Grok logout removes `.api-key`, `.env`, and `.grok` credential material for the selected label.\n- Grok env bridge exports empty values for missing optional API-key vars instead of failing shell startup.\n\n## Tests\n- `bun --cwd packages/lib vitest run tests/core/templates.test.ts`\n- `bun --cwd packages/lib vitest run tests/usecases/agent-auto-select.test.ts`\n- `bun run typecheck`\n- `bun run lint`\n- `bun run lint:effect`\n- `bun run --filter @effect-template/api lint`\n- `bun run test`\n- `bun run api:test`\n- Targeted: `packages/lib` Grok auth/template/auto-select tests, `packages/app` Grok parser test, `packages/api` agent command test.\n\n## Notes\n- No screenshots: this change is functional/API/template wiring rather than visual UI work.\n- SOURCE: npm package metadata and CLI behavior for `grok-dev@latest` were used during implementation research.","headRefName":"issue-304-3b5ced26375c","headRepository":{"id":"R_kgDORZMURA","name":"ProverCoderAI-docker-git","nameWithOwner":"konard/ProverCoderAI-docker-git"},"headRepositoryOwner":{"id":"MDQ6VXNlcjE0MzE5MDQ=","name":"Konstantin Diachenko","login":"konard"},"mergeStateStatus":"CLEAN","number":305,"state":"OPEN"}
[2026-05-17T13:17:50.370Z] [INFO] 🍴 Detected fork PR from konard/ProverCoderAI-docker-git
[2026-05-17T13:17:50.371Z] [INFO]    Fork owner: konard
[2026-05-17T13:17:50.371Z] [INFO]    Will clone fork repository for continue mode
[2026-05-17T13:17:50.371Z] [INFO] 📝 PR branch: issue-304-3b5ced26375c
[2026-05-17T13:17:50.372Z] [INFO] 🔗 Found linked issue #304
[2026-05-17T13:17:50.378Z] [INFO] 
[2026-05-17T13:17:50.378Z] [INFO] Creating temporary directory: /tmp/gh-issue-solver-1779023870373
[2026-05-17T13:17:50.381Z] [INFO] 
[2026-05-17T13:17:50.381Z] [INFO] 🍴 Fork mode:                ENABLED
[2026-05-17T13:17:50.381Z] [INFO]  Checking fork status...   
[2026-05-17T13:17:50.381Z] [INFO] 
[2026-05-17T13:17:50.716Z] [STDOUT] konard
[2026-05-17T13:17:50.721Z] [INFO] 🔍 Detecting fork conflicts... 
[2026-05-17T13:17:51.084Z] [STDOUT] {"fork":false,"source":null}
[2026-05-17T13:17:51.441Z] [STDOUT] konard
[2026-05-17T13:17:51.877Z] [STDOUT] konard/ProverCoderAI-docker-git
[2026-05-17T13:17:51.882Z] [INFO] ✅ No fork conflict:         Safe to proceed
[2026-05-17T13:17:52.150Z] [STDOUT] {"name":"ProverCoderAI-docker-git"}
[2026-05-17T13:17:52.155Z] [INFO] ✅ Fork exists:              konard/ProverCoderAI-docker-git
[2026-05-17T13:17:52.156Z] [INFO] 🔍 Validating fork parent... 
[2026-05-17T13:17:52.485Z] [STDOUT] {"fork":true,"parent":"ProverCoderAI/docker-git","source":"ProverCoderAI/docker-git"}
[2026-05-17T13:17:52.490Z] [INFO] ✅ Fork parent validated:    ProverCoderAI/docker-git
[2026-05-17T13:17:52.491Z] [INFO] 
[2026-05-17T13:17:52.491Z] [INFO] 📥 Cloning repository:       konard/ProverCoderAI-docker-git
[2026-05-17T13:17:52.944Z] [STDOUT] Cloning into '/tmp/gh-issue-solver-1779023870373'...
[2026-05-17T13:18:08.224Z] [STDOUT] Updating files:   3% (29/949)
[2026-05-17T13:18:09.095Z] [STDOUT] Updating files:   3% (34/949)
[2026-05-17T13:18:09.379Z] [STDOUT] Updating files:   4% (38/949)
[2026-05-17T13:18:10.082Z] [STDOUT] Updating files:   4% (43/949)
[2026-05-17T13:18:10.533Z] [STDOUT] Updating files:   5% (48/949)
[2026-05-17T13:18:10.793Z] [STDOUT] Updating files:   6% (57/949)
[2026-05-17T13:18:10.794Z] [STDOUT] Updating files:   7% (67/949)
[2026-05-17T13:18:10.795Z] [STDOUT] Updating files:   8% (76/949)
[2026-05-17T13:18:10.797Z] [STDOUT] Updating files:   9% (86/949)
[2026-05-17T13:18:10.801Z] [STDOUT] Updating files:  10% (95/949)
[2026-05-17T13:18:10.804Z] [STDOUT] Updating files:  11% (105/949)
[2026-05-17T13:18:10.806Z] [STDOUT] Updating files:  12% (114/949)
[2026-05-17T13:18:10.810Z] [STDOUT] Updating files:  13% (124/949)
[2026-05-17T13:18:10.811Z] [STDOUT] Updating files:  14% (133/949)
[2026-05-17T13:18:10.811Z] [STDOUT] Updating files:  15% (143/949)
[2026-05-17T13:18:10.812Z] [STDOUT] Updating files:  16% (152/949)
[2026-05-17T13:18:10.813Z] [STDOUT] Updating files:  17% (162/949)
[2026-05-17T13:18:10.814Z] [STDOUT] Updating files:  18% (171/949)
[2026-05-17T13:18:10.815Z] [STDOUT] Updating files:  19% (181/949)
[2026-05-17T13:18:10.816Z] [STDOUT] Updating files:  20% (190/949)
[2026-05-17T13:18:10.817Z] [STDOUT] Updating files:  21% (200/949)
[2026-05-17T13:18:10.817Z] [STDOUT] Updating files:  22% (209/949)
[2026-05-17T13:18:10.818Z] [STDOUT] Updating files:  23% (219/949)
[2026-05-17T13:18:10.819Z] [STDOUT] Updating files:  24% (228/949)
[2026-05-17T13:18:10.820Z] [STDOUT] Updating files:  25% (238/949)
[2026-05-17T13:18:10.820Z] [STDOUT] Updating files:  26% (247/949)
[2026-05-17T13:18:10.821Z] [STDOUT] Updating files:  27% (257/949)
[2026-05-17T13:18:10.821Z] [STDOUT] Updating files:  28% (266/949)
[2026-05-17T13:18:10.822Z] [STDOUT] Updating files:  29% (276/949)
[2026-05-17T13:18:10.823Z] [STDOUT] Updating files:  30% (285/949)
[2026-05-17T13:18:10.824Z] [STDOUT] Updating files:  31% (295/949)
[2026-05-17T13:18:10.824Z] [STDOUT] Updating files:  32% (304/949)
[2026-05-17T13:18:10.825Z] [STDOUT] Updating files:  33% (314/949)
[2026-05-17T13:18:10.825Z] [STDOUT] Updating files:  34% (323/949)
[2026-05-17T13:18:10.826Z] [STDOUT] Updating files:  35% (333/949)
[2026-05-17T13:18:10.827Z] [STDOUT] Updating files:  36% (342/949)
[2026-05-17T13:18:10.828Z] [STDOUT] Updating files:  37% (352/949)
[2026-05-17T13:18:10.828Z] [STDOUT] Updating files:  38% (361/949)
[2026-05-17T13:18:10.829Z] [STDOUT] Updating files:  39% (371/949)
[2026-05-17T13:18:10.830Z] [STDOUT] Updating files:  40% (380/949)
[2026-05-17T13:18:10.831Z] [STDOUT] Updating files:  41% (390/949)
[2026-05-17T13:18:10.831Z] [STDOUT] Updating files:  42% (399/949)
[2026-05-17T13:18:10.832Z] [STDOUT] Updating files:  43% (409/949)
[2026-05-17T13:18:10.833Z] [STDOUT] Updating files:  44% (418/949)
[2026-05-17T13:18:10.834Z] [STDOUT] Updating files:  45% (428/949)
[2026-05-17T13:18:10.834Z] [STDOUT] Updating files:  46% (437/949)
[2026-05-17T13:18:10.835Z] [STDOUT] Updating files:  47% (447/949)
[2026-05-17T13:18:10.836Z] [STDOUT] Updating files:  48% (456/949)
[2026-05-17T13:18:10.836Z] [STDOUT] Updating files:  49% (466/949)
[2026-05-17T13:18:10.837Z] [STDOUT] Updating files:  50% (475/949)
[2026-05-17T13:18:10.838Z] [STDOUT] Updating files:  51% (484/949)
[2026-05-17T13:18:10.838Z] [STDOUT] Updating files:  52% (494/949)
[2026-05-17T13:18:10.839Z] [STDOUT] Updating files:  53% (503/949)
[2026-05-17T13:18:10.839Z] [STDOUT] Updating files:  54% (513/949)
[2026-05-17T13:18:10.840Z] [STDOUT] Updating files:  55% (522/949)
[2026-05-17T13:18:10.840Z] [STDOUT] Updating files:  56% (532/949)
[2026-05-17T13:18:10.841Z] [STDOUT] Updating files:  57% (541/949)
[2026-05-17T13:18:10.842Z] [STDOUT] Updating files:  58% (551/949)
[2026-05-17T13:18:10.842Z] [STDOUT] Updating files:  59% (560/949)
[2026-05-17T13:18:10.843Z] [STDOUT] Updating files:  60% (570/949)
[2026-05-17T13:18:10.844Z] [STDOUT] Updating files:  61% (579/949)
[2026-05-17T13:18:10.844Z] [STDOUT] Updating files:  62% (589/949)
[2026-05-17T13:18:10.845Z] [STDOUT] Updating files:  63% (598/949)
[2026-05-17T13:18:10.846Z] [STDOUT] Updating files:  64% (608/949)
[2026-05-17T13:18:10.846Z] [STDOUT] Updating files:  65% (617/949)
[2026-05-17T13:18:10.847Z] [STDOUT] Updating files:  66% (627/949)
[2026-05-17T13:18:10.848Z] [STDOUT] Updating files:  67% (636/949)
[2026-05-17T13:18:10.849Z] [STDOUT] Updating files:  68% (646/949)
[2026-05-17T13:18:10.849Z] [STDOUT] Updating files:  69% (655/949)
[2026-05-17T13:18:10.850Z] [STDOUT] Updating files:  70% (665/949)
[2026-05-17T13:18:10.850Z] [STDOUT] Updating files:  71% (674/949)
[2026-05-17T13:18:10.851Z] [STDOUT] Updating files:  72% (684/949)
[2026-05-17T13:18:10.852Z] [STDOUT] Updating files:  73% (693/949)
[2026-05-17T13:18:10.853Z] [STDOUT] Updating files:  74% (703/949)
[2026-05-17T13:18:10.854Z] [STDOUT] Updating files:  75% (712/949)
[2026-05-17T13:18:10.854Z] [STDOUT] Updating files:  76% (722/949)
[2026-05-17T13:18:10.855Z] [STDOUT] Updating files:  77% (731/949)
[2026-05-17T13:18:10.856Z] [STDOUT] Updating files:  78% (741/949)
[2026-05-17T13:18:10.856Z] [STDOUT] Updating files:  79% (750/949)
[2026-05-17T13:18:10.857Z] [STDOUT] Updating files:  80% (760/949)
[2026-05-17T13:18:10.858Z] [STDOUT] Updating files:  81% (769/949)
[2026-05-17T13:18:10.858Z] [STDOUT] Updating files:  82% (779/949)
[2026-05-17T13:18:10.859Z] [STDOUT] Updating files:  83% (788/949)
[2026-05-17T13:18:10.860Z] [STDOUT] Updating files:  84% (798/949)
[2026-05-17T13:18:10.861Z] [STDOUT] Updating files:  85% (807/949)
[2026-05-17T13:18:10.861Z] [STDOUT] Updating files:  86% (817/949)
[2026-05-17T13:18:10.862Z] [STDOUT] Updating files:  87% (826/949)
[2026-05-17T13:18:10.862Z] [STDOUT] Updating files:  88% (836/949)
[2026-05-17T13:18:10.863Z] [STDOUT] Updating files:  89% (845/949)
[2026-05-17T13:18:10.864Z] [STDOUT] Updating files:  90% (855/949)
[2026-05-17T13:18:10.864Z] [STDOUT] Updating files:  91% (864/949)
[2026-05-17T13:18:10.865Z] [STDOUT] Updating files:  92% (874/949)
[2026-05-17T13:18:10.866Z] [STDOUT] Updating files:  93% (883/949)
[2026-05-17T13:18:10.867Z] [STDOUT] Updating files:  94% (893/949)
[2026-05-17T13:18:10.868Z] [STDOUT] Updating files:  95% (902/949)
[2026-05-17T13:18:10.868Z] [STDOUT] Updating files:  96% (912/949)
[2026-05-17T13:18:10.869Z] [STDOUT] Updating files:  97% (921/949)
[2026-05-17T13:18:10.870Z] [STDOUT] Updating files:  98% (931/949)
[2026-05-17T13:18:10.871Z] [STDOUT] Updating files:  99% (940/949)
[2026-05-17T13:18:10.871Z] [STDOUT] Updating files: 100% (949/949)
Updating files: 100% (949/949), done.
[2026-05-17T13:18:11.734Z] [STDOUT] From https://github.com/ProverCoderAI/docker-git
 * [new branch]      main       -> upstream/main
[2026-05-17T13:18:11.734Z] [STDOUT]  * [new tag]         docker-git-session-sync-v1.0.2 -> docker-git-session-sync-v1.0.2
 * [new tag]         v1.0.27    -> v1.0.27
 * [new tag]         v1.0.28    -> v1.0.28
 * [new tag]         v1.0.29    -> v1.0.29
[2026-05-17T13:18:11.734Z] [STDOUT]  * [new tag]         v1.0.30    -> v1.0.30
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.31    -> v1.0.31
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.32    -> v1.0.32
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.33    -> v1.0.33
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.34    -> v1.0.34
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.35    -> v1.0.35
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.36    -> v1.0.36
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.37    -> v1.0.37
[2026-05-17T13:18:11.735Z] [STDOUT]  * [new tag]         v1.0.38    -> v1.0.38
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.39    -> v1.0.39
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.40    -> v1.0.40
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.41    -> v1.0.41
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.42    -> v1.0.42
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.43    -> v1.0.43
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.44    -> v1.0.44
[2026-05-17T13:18:11.736Z] [STDOUT]  * [new tag]         v1.0.45    -> v1.0.45
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.46    -> v1.0.46
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.47    -> v1.0.47
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.48    -> v1.0.48
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.49    -> v1.0.49
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.50    -> v1.0.50
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.51    -> v1.0.51
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.52    -> v1.0.52
[2026-05-17T13:18:11.737Z] [STDOUT]  * [new tag]         v1.0.53    -> v1.0.53
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.54    -> v1.0.54
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.55    -> v1.0.55
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.56    -> v1.0.56
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.57    -> v1.0.57
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.58    -> v1.0.58
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.59    -> v1.0.59
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.60    -> v1.0.60
[2026-05-17T13:18:11.738Z] [STDOUT]  * [new tag]         v1.0.61    -> v1.0.61
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.62    -> v1.0.62
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.63    -> v1.0.63
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.64    -> v1.0.64
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.65    -> v1.0.65
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.66    -> v1.0.66
[2026-05-17T13:18:11.739Z] [STDOUT]  * [new tag]         v1.0.67    -> v1.0.67
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.68    -> v1.0.68
 * [new tag]         v1.0.69    -> v1.0.69
 * [new tag]         v1.0.70    -> v1.0.70
 * [new tag]         v1.0.71    -> v1.0.71
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.72    -> v1.0.72
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.73    -> v1.0.73
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.74    -> v1.0.74
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.75    -> v1.0.75
[2026-05-17T13:18:11.740Z] [STDOUT]  * [new tag]         v1.0.76    -> v1.0.76
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.77    -> v1.0.77
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.78    -> v1.0.78
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.79    -> v1.0.79
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.80    -> v1.0.80
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.81    -> v1.0.81
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.82    -> v1.0.82
[2026-05-17T13:18:11.741Z] [STDOUT]  * [new tag]         v1.0.84    -> v1.0.84
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.0.85    -> v1.0.85
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.0.86    -> v1.0.86
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.0.87    -> v1.0.87
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.1.0     -> v1.1.0
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.1.10    -> v1.1.10
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.1.11    -> v1.1.11
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.1.12    -> v1.1.12
[2026-05-17T13:18:11.742Z] [STDOUT]  * [new tag]         v1.1.13    -> v1.1.13
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.3     -> v1.1.3
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.4     -> v1.1.4
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.5     -> v1.1.5
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.6     -> v1.1.6
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.8     -> v1.1.8
[2026-05-17T13:18:11.743Z] [STDOUT]  * [new tag]         v1.1.9     -> v1.1.9
[2026-05-17T13:18:11.761Z] [INFO] ✅ Cloned to:                /tmp/gh-issue-solver-1779023870373
[2026-05-17T13:18:11.770Z] [STDOUT] origin	https://github.com/konard/ProverCoderAI-docker-git.git (fetch)
origin	https://github.com/konard/ProverCoderAI-docker-git.git (push)
upstream	https://github.com/ProverCoderAI/docker-git.git (fetch)
upstream	https://github.com/ProverCoderAI/docker-git.git (push)
[2026-05-17T13:18:11.772Z] [INFO] 🔗 Setting upstream:         ProverCoderAI/docker-git
[2026-05-17T13:18:11.781Z] [STDOUT] https://github.com/ProverCoderAI/docker-git.git
[2026-05-17T13:18:11.782Z] [INFO] ℹ️ Upstream exists:          Using existing upstream remote
[2026-05-17T13:18:11.783Z] [INFO] 🔄 Fetching upstream...      
[2026-05-17T13:18:12.621Z] [STDERR] From https://github.com/ProverCoderAI/docker-git
 * [new branch]      chore/hosted-oss-review-agents -> upstream/chore/hosted-oss-review-agents
[2026-05-17T13:18:12.621Z] [STDERR]  * [new branch]      chore/issue-7-workflow-sync -> upstream/chore/issue-7-workflow-sync
 * [new branch]      chore/simplify-coderabbit-spec-prompt -> upstream/chore/simplify-coderabbit-spec-prompt
 * [new branch]      ci/issue-75-open-command -> upstream/ci/issue-75-open-command
 * [new branch]      codex-docker-resource-limits-network -> upstream/codex-docker-resource-limits-network
[2026-05-17T13:18:12.621Z] [STDERR]  * [new branch]      codex/c7f9577-runtime-identities -> upstream/codex/c7f9577-runtime-identities
[2026-05-17T13:18:12.621Z] [STDERR]  * [new branch]      codex/ci-e2e-ssh-checks -> upstream/codex/ci-e2e-ssh-checks
[2026-05-17T13:18:12.621Z] [STDERR]  * [new branch]      codex/mcp-playwright-cdp-guard -> upstream/codex/mcp-playwright-cdp-guard
[2026-05-17T13:18:12.621Z] [STDERR]  * [new branch]      codex/shared-browser-agent-isolation -> upstream/codex/shared-browser-agent-isolation
[2026-05-17T13:18:12.622Z] [STDERR]  * [new branch]      docs-readme-short      -> upstream/docs-readme-short
[2026-05-17T13:18:12.622Z] [STDERR]  * [new branch]      docs/update-readme-bun-workflow -> upstream/docs/update-readme-bun-workflow
[2026-05-17T13:18:12.622Z] [STDERR]  * [new branch]      feat-auto-agent-selection -> upstream/feat-auto-agent-selection
[2026-05-17T13:18:12.622Z] [STDERR]  * [new branch]      feat/bun-gridland-bun-first -> upstream/feat/bun-gridland-bun-first
[2026-05-17T13:18:12.623Z] [STDERR]  * [new branch]      feat/extract-claude-system-prompt -> upstream/feat/extract-claude-system-prompt
[2026-05-17T13:18:12.623Z] [STDERR]  * [new branch]      feat/parallel-issue-workspaces -> upstream/feat/parallel-issue-workspaces
[2026-05-17T13:18:12.624Z] [STDERR]  * [new branch]      fix-auto-agent         -> upstream/fix-auto-agent
 * [new branch]      fix-federation-status-route -> upstream/fix-federation-status-route
 * [new branch]      fix/browser-web-restart -> upstream/fix/browser-web-restart
[2026-05-17T13:18:12.624Z] [STDERR]  * [new branch]      fix/ci-check-github-token-validation -> upstream/fix/ci-check-github-token-validation
[2026-05-17T13:18:12.624Z] [STDERR]  * [new branch]      fix/ci-checkout-permissions -> upstream/fix/ci-checkout-permissions
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/ci-controller-gpu-opt-in -> upstream/fix/ci-controller-gpu-opt-in
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/ci-docker-git-checks -> upstream/fix/ci-docker-git-checks
 * [new branch]      fix/effect-lint-tests  -> upstream/fix/effect-lint-tests
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/federation-jsonld-context -> upstream/fix/federation-jsonld-context
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/force-env-refresh-managed -> upstream/fix/force-env-refresh-managed
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/isolated-docker-runtime -> upstream/fix/isolated-docker-runtime
[2026-05-17T13:18:12.625Z] [STDERR]  * [new branch]      fix/issue-11-docker-sock-permission -> upstream/fix/issue-11-docker-sock-permission
[2026-05-17T13:18:12.626Z] [STDERR]  * [new branch]      fix/issue-21-check-app-lib -> upstream/fix/issue-21-check-app-lib
[2026-05-17T13:18:12.627Z] [STDERR]  * [new branch]      fix/release-only-app-publish -> upstream/fix/release-only-app-publish
 * [new branch]      fix/restore-check-workflow -> upstream/fix/restore-check-workflow
 * [new branch]      issue-10-fix           -> upstream/issue-10-fix
 * [new branch]      issue-108              -> upstream/issue-108
 * [new branch]      issue-111              -> upstream/issue-111
 * [new branch]      issue-12-fix           -> upstream/issue-12-fix
 * [new branch]      issue-132              -> upstream/issue-132
 * [new branch]      issue-137              -> upstream/issue-137
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-14-fix           -> upstream/issue-14-fix
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-141              -> upstream/issue-141
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-158              -> upstream/issue-158
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-163              -> upstream/issue-163
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-192              -> upstream/issue-192
[2026-05-17T13:18:12.628Z] [STDERR]  * [new branch]      issue-198              -> upstream/issue-198
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-230              -> upstream/issue-230
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-232              -> upstream/issue-232
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-233              -> upstream/issue-233
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-237-d4e1e2d53afd -> upstream/issue-237-d4e1e2d53afd
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-239              -> upstream/issue-239
[2026-05-17T13:18:12.629Z] [STDERR]  * [new branch]      issue-24-sub-docker-git -> upstream/issue-24-sub-docker-git
[2026-05-17T13:18:12.630Z] [STDERR]  * [new branch]      issue-250              -> upstream/issue-250
[2026-05-17T13:18:12.630Z] [STDERR]  * [new branch]      issue-251              -> upstream/issue-251
[2026-05-17T13:18:12.630Z] [STDERR]  * [new branch]      issue-252              -> upstream/issue-252
[2026-05-17T13:18:12.630Z] [STDERR]  * [new branch]      issue-27               -> upstream/issue-27
[2026-05-17T13:18:12.630Z] [STDERR]  * [new branch]      issue-273              -> upstream/issue-273
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      issue-282              -> upstream/issue-282
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      issue-39               -> upstream/issue-39
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      issue-61               -> upstream/issue-61
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      issue-84               -> upstream/issue-84
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      pr-268                 -> upstream/pr-268
[2026-05-17T13:18:12.631Z] [STDERR]  * [new branch]      smoke-prehook-source-160 -> upstream/smoke-prehook-source-160
[2026-05-17T13:18:12.639Z] [INFO] ✅ Upstream fetched:         Successfully
[2026-05-17T13:18:12.640Z] [INFO] 🔄 Syncing default branch... 
[2026-05-17T13:18:12.647Z] [STDOUT] main
[2026-05-17T13:18:12.995Z] [STDOUT] main
[2026-05-17T13:18:12.999Z] [INFO] ℹ️ Default branch:           main
[2026-05-17T13:18:13.534Z] [STDOUT] HEAD is now at d42045c chore(deps): update dependency jscpd to ^4.2.3 (#307)
[2026-05-17T13:18:13.535Z] [INFO] ✅ Default branch synced:    with upstream/main
[2026-05-17T13:18:13.536Z] [INFO] 🔄 Pushing to fork:          main branch
[2026-05-17T13:18:14.042Z] [STDOUT] To https://github.com/konard/ProverCoderAI-docker-git.git
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'https://github.com/konard/ProverCoderAI-docker-git.git'
[2026-05-17T13:18:14.047Z] [STDOUT] hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
[2026-05-17T13:18:14.048Z] [INFO] 
[2026-05-17T13:18:14.048Z] [WARN] ⚠️ FORK DIVERGENCE DETECTED  
[2026-05-17T13:18:14.048Z] [INFO] 
[2026-05-17T13:18:14.048Z] [INFO]   🔍 What happened:
[2026-05-17T13:18:14.049Z] [INFO]      Your fork's main branch has different commits than upstream
[2026-05-17T13:18:14.049Z] [INFO]      This typically occurs when upstream had a force push (e.g., git reset --hard)
[2026-05-17T13:18:14.049Z] [INFO] 
[2026-05-17T13:18:14.049Z] [INFO]   📦 Current state:
[2026-05-17T13:18:14.049Z] [INFO]      • Fork: konard/ProverCoderAI-docker-git
[2026-05-17T13:18:14.049Z] [INFO]      • Upstream: ProverCoderAI/docker-git
[2026-05-17T13:18:14.049Z] [INFO]      • Branch: main
[2026-05-17T13:18:14.049Z] [INFO] 
[2026-05-17T13:18:14.049Z] [INFO]   💡 Your options:
[2026-05-17T13:18:14.050Z] [INFO] 
[2026-05-17T13:18:14.050Z] [INFO]      Option 1: Delete your fork and recreate it (SIMPLEST)
[2026-05-17T13:18:14.050Z] [INFO]               gh repo delete konard/ProverCoderAI-docker-git
[2026-05-17T13:18:14.050Z] [INFO]               Then run the solve command again - the fork will be recreated automatically
[2026-05-17T13:18:14.050Z] [INFO]               ⚠️  Only use this if your fork has no unique commits you need to preserve
[2026-05-17T13:18:14.050Z] [INFO] 
[2026-05-17T13:18:14.050Z] [INFO]      Option 2: Enable automatic force-push (DANGEROUS)
[2026-05-17T13:18:14.050Z] [INFO]               Add --allow-fork-divergence-resolution-using-force-push-with-lease flag to your command
[2026-05-17T13:18:14.050Z] [INFO]               This will automatically sync your fork with upstream using force-with-lease
[2026-05-17T13:18:14.051Z] [INFO]               ⚠️  Overwrites fork history - any unique commits will be LOST
[2026-05-17T13:18:14.051Z] [INFO] 
[2026-05-17T13:18:14.051Z] [INFO]      Option 3: Manually resolve the divergence
[2026-05-17T13:18:14.051Z] [INFO]               1. Decide if you need any commits unique to your fork
[2026-05-17T13:18:14.051Z] [INFO]               2. If yes, cherry-pick them after syncing
[2026-05-17T13:18:14.051Z] [INFO]               3. If no, manually force-push:
[2026-05-17T13:18:14.051Z] [INFO]                  git fetch upstream
[2026-05-17T13:18:14.051Z] [INFO]                  git reset --hard upstream/main
[2026-05-17T13:18:14.051Z] [INFO]                  git push --force origin main
[2026-05-17T13:18:14.052Z] [INFO] 
[2026-05-17T13:18:14.052Z] [INFO]   🔧 To proceed with auto-resolution, restart with:
[2026-05-17T13:18:14.052Z] [INFO]      solve https://github.com/ProverCoderAI/docker-git/pull/305 --allow-fork-divergence-resolution-using-force-push-with-lease
[2026-05-17T13:18:14.052Z] [INFO] 
[2026-05-17T13:18:14.053Z] [INFO] 
[2026-05-17T13:18:14.053Z] [ERROR] ❌ Repository setup halted - fork divergence requires user decision
[2026-05-17T13:18:14.053Z] [INFO] 📁 Full log file: /home/box/solve-2026-05-17T13-17-40-867Z.log
[2026-05-17T13:18:14.054Z] [INFO] 
[2026-05-17T13:18:14.054Z] [INFO] 📄 Notifying pull request #305 about solver failure with logs...
[2026-05-17T13:18:14.200Z] [INFO]   🤖 Model info fetched for comment


Now working session is ended, feel free to review and add any feedback on the solution draft.

@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: d3238f4
Status: success
Files: 9 (16.23 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/api/src/http.ts (1)

429-448: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Замените switch на Match и удалите type assertion as ProjectSkillScope в маппинге skill scope.

Функции skillScopeFromId (строки 429–448), skillScopeToId (строки 450–467) и skillScopeFromBody (строки 469–482) используют switch и type assertion, которые запрещены по гайдлайнам. Замените на исчерпывающий разбор с помощью Match.exhaustive():

Пример рефакторинга
-const skillScopeFromBody = (scope: string): ProjectSkillScope | null => {
-  switch (scope) {
-    case "skills":
-    case "agents/skills":
-    case "agents/.skills":
-    case "claude/skills":
-    case "codex/skills":
-    case "gemini/skills":
-    case "grok/skills":
-      return scope as ProjectSkillScope
-    default:
-      return null
-  }
-}
+const skillScopeFromBody = (scope: string): ProjectSkillScope | null =>
+  Match.value(scope).pipe(
+    Match.when("skills", () => "skills"),
+    Match.when("agents/skills", () => "agents/skills"),
+    Match.when("agents/.skills", () => "agents/.skills"),
+    Match.when("claude/skills", () => "claude/skills"),
+    Match.when("codex/skills", () => "codex/skills"),
+    Match.when("gemini/skills", () => "gemini/skills"),
+    Match.when("grok/skills", () => "grok/skills"),
+    Match.orElse(() => null)
+  )

Это применяется также к skillScopeToId (строки 450–467) и skillScopeFromId (строки 429–448).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/http.ts` around lines 429 - 448, Replace the switch-based,
asserted mappings in skillScopeFromId, skillScopeToId, and skillScopeFromBody
with exhaustive pattern matches using Match.exhaustive(); specifically, remove
any "as ProjectSkillScope" assertions, import and use Match (e.g. from
ts-pattern) to match each possible string/enum case and return the correctly
typed ProjectSkillScope or id string, and ensure the match is exhaustive so the
default/null branch is handled by Match.exhaustive() instead of a fallback
switch/default. Use the function names skillScopeFromId, skillScopeToId, and
skillScopeFromBody as anchors when applying the refactor.
♻️ Duplicate comments (4)
packages/app/src/lib/usecases/auth-grok-helpers.ts (2)

54-65: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Закрепите версию grok-dev вместо @latest --force.

Использование grok-dev@latest --force делает сборку Docker-образа недетерминированной: один коммит может проходить сегодня и падать завтра после выхода новой версии пакета. Для воспроизводимых сборок замените на конкретную версию без --force.

🔧 Предлагаемое исправление
-RUN npm install -g grok-dev@latest --force
+RUN npm install -g grok-dev@1.1.6
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 54 - 65, The
Dockerfile generator renderGrokDockerfile currently installs grok-dev with "npm
install -g grok-dev@latest --force", which makes builds nondeterministic; change
that line in renderGrokDockerfile to pin a specific semantic version (e.g.
grok-dev@X.Y.Z) and remove the "--force" flag so the image is reproducible and
not forced to override versions. Update the string returned by
renderGrokDockerfile to use the chosen fixed version token in place of "`@latest`
--force".

204-218: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ошибки fallback-удаления credentials директории подавляются.

Если fs.remove и docker-fallback оба провалятся, Effect.asVoid превратит ошибку в успех, и код продолжит работу поверх старого каталога. Новый логин может унаследовать артефакты предыдущей сессии.

🔧 Предлагаемое исправление
     const removeFallback = pipe(
       runCommandExitCode({
         cwd,
         command: "docker",
         args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]
       }),
-      Effect.asVoid
+      Effect.asVoid,
+      Effect.mapError((err) => err)  // propagate error instead of swallowing
     )

     yield* _(
       fs.remove(credentialsDir, { recursive: true, force: true }).pipe(
-        Effect.orElse(() => removeFallback)
+        Effect.orElse(() => removeFallback),
+        Effect.orElse(() => Effect.void)  // only swallow after both attempts
       )
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 204 - 218, В
текущем Effect.gen блоке удаление credentialsDir использует
fs.remove(...).pipe(Effect.orElse(() => removeFallback)) и затем removeFallback
обёрнут в Effect.asVoid, из-за чего ошибки обоих путей подавляются; исправьте
так, чтобы при провале и fs.remove, и runCommandExitCode (removeFallback) ошибка
пробрасывалась: уберите Effect.asVoid с removeFallback, вместо Effect.orElse
используйте объединяющий обработчик (например,
Effect.orElseFail/Effect.catchAll) который собирает/пробрасывает оригинальную
ошибку или новый агрегированный Error и возвращает Effect.fail; сослаться на
символы grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove и
Effect.asVoid при правке.
packages/lib/src/usecases/auth-grok-helpers.ts (2)

203-218: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Ошибки fallback-удаления credentials директории подавляются.

Аналогичная проблема как в packages/app: если оба способа удаления провалятся, ошибка будет подавлена.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 203 - 218, The
fallback deletion in Effect.gen around grokCredentialsPath uses
fs.remove(...).pipe(Effect.orElse(() => removeFallback)) which swallows errors
if both fs.remove and removeFallback fail; update this to rethrow a
composed/error from the failures instead of suppressing it: replace the
Effect.orElse call so that on fs.remove failure you run removeFallback and if
removeFallback also fails you propagate an error (e.g., using Effect.orElseFail
or Effect.catchAll to map the second failure into a failing Effect) so the
overall effect fails instead of being silently ignored; reference symbols:
Effect.gen, grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove.

53-64: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Закрепите версию grok-dev вместо @latest --force.

Аналогичная проблема как в packages/app: использование grok-dev@latest --force делает сборку недетерминированной.

🔧 Предлагаемое исправление
-RUN npm install -g grok-dev@latest --force
+RUN npm install -g grok-dev@1.1.6
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 53 - 64, The
Dockerfile generator renderGrokDockerfile currently installs grok-dev using an
undetermined tag ("grok-dev@latest --force"), making builds non-deterministic;
change the npm install line inside renderGrokDockerfile to pin a specific
released version (e.g. "grok-dev@<MAJOR.MINOR.PATCH>") and remove the --force
flag so the image is reproducible and predictable, then update any docs/tests
that expect the previous behavior to use the pinned version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 239-259: The oauth marker /"oauth"\s*:/u is too permissive and
flags an oauth block even when empty; update the
grokUserSettingsCredentialMarkers array (used by hasGrokUserSettingsCredentials)
to replace the current oauth regex with a stricter pattern that requires a
non-empty credential inside the oauth object (e.g. require a string-valued key
like "token", "accessToken", "apiKey" or "access_token" with a non-empty value),
so the detector only returns true when an actual secret is present.

In `@packages/lib/tests/core/templates.test.ts`:
- Around line 218-226: Тест "installs Grok CLI for generated project containers"
asserts the Dockerfile contains the hardcoded string "npm install -g
grok-dev@latest --force", which is brittle once the version is pinned; update
the test in packages/lib/tests/core/templates.test.ts to assert on a less
fragile pattern by checking for "npm install -g grok-dev" (or a regex like "npm
install -g grok-dev(@|@\\d+)") instead of the exact "`@latest` --force" token,
locating the assertion in the spec that calls
renderDockerfile(makeTemplateConfig()) and adjusts the
expectContainsAll/expect(...) checks accordingly.

In `@packages/lib/tests/usecases/auth-grok.test.ts`:
- Around line 56-106: Add a negative test that verifies authGrokLogin rejects
empty and whitespace-only API keys: create a new it.effect in the same test
suite (use withTempDir and withPatchedEnv like the existing test) and call
authGrokLogin with "" and with "   " (space-only) providing FileSystem and Path
via Effect.provideService; assert the Effect fails (typed-failure) rather than
succeeds by inspecting the Effect exit/error (e.g., run/exit or expecting a
failure/error type/message) and ensure the failure matches the login validation
invariant for empty API keys rather than writing files; reference authGrokLogin,
withTempDir, withPatchedEnv, FileSystem.FileSystem and Path.Path to locate where
to add the checks.
- Around line 107-143: Add fast-check property-based tests to auth-grok.test.ts
that generate many JSON payloads and assert the invariants for
hasGrokCredentials: use fc.property to produce (1) valid JSON objects that
always include an "apiKey" string and verify hasGrokCredentials(fs, accountPath)
returns true, and (2) valid JSON objects that explicitly do NOT include "apiKey"
but match bootstrap-like shapes (e.g., may include "sandboxMode" or
"confirmBeforeToolUse") and verify hasGrokCredentials(...) returns false; reuse
the existing withTempDir, FileSystem.FileSystem and Path.Path setup, write the
generated JSON to path.join(credentialsDir, "user-settings.json"), and call
fc.assert with reasonable limits to integrate into the test suite.

---

Outside diff comments:
In `@packages/api/src/http.ts`:
- Around line 429-448: Replace the switch-based, asserted mappings in
skillScopeFromId, skillScopeToId, and skillScopeFromBody with exhaustive pattern
matches using Match.exhaustive(); specifically, remove any "as
ProjectSkillScope" assertions, import and use Match (e.g. from ts-pattern) to
match each possible string/enum case and return the correctly typed
ProjectSkillScope or id string, and ensure the match is exhaustive so the
default/null branch is handled by Match.exhaustive() instead of a fallback
switch/default. Use the function names skillScopeFromId, skillScopeToId, and
skillScopeFromBody as anchors when applying the refactor.

---

Duplicate comments:
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 54-65: The Dockerfile generator renderGrokDockerfile currently
installs grok-dev with "npm install -g grok-dev@latest --force", which makes
builds nondeterministic; change that line in renderGrokDockerfile to pin a
specific semantic version (e.g. grok-dev@X.Y.Z) and remove the "--force" flag so
the image is reproducible and not forced to override versions. Update the string
returned by renderGrokDockerfile to use the chosen fixed version token in place
of "`@latest` --force".
- Around line 204-218: В текущем Effect.gen блоке удаление credentialsDir
использует fs.remove(...).pipe(Effect.orElse(() => removeFallback)) и затем
removeFallback обёрнут в Effect.asVoid, из-за чего ошибки обоих путей
подавляются; исправьте так, чтобы при провале и fs.remove, и runCommandExitCode
(removeFallback) ошибка пробрасывалась: уберите Effect.asVoid с removeFallback,
вместо Effect.orElse используйте объединяющий обработчик (например,
Effect.orElseFail/Effect.catchAll) который собирает/пробрасывает оригинальную
ошибку или новый агрегированный Error и возвращает Effect.fail; сослаться на
символы grokCredentialsPath, removeFallback, runCommandExitCode, fs.remove и
Effect.asVoid при правке.

In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 203-218: The fallback deletion in Effect.gen around
grokCredentialsPath uses fs.remove(...).pipe(Effect.orElse(() =>
removeFallback)) which swallows errors if both fs.remove and removeFallback
fail; update this to rethrow a composed/error from the failures instead of
suppressing it: replace the Effect.orElse call so that on fs.remove failure you
run removeFallback and if removeFallback also fails you propagate an error
(e.g., using Effect.orElseFail or Effect.catchAll to map the second failure into
a failing Effect) so the overall effect fails instead of being silently ignored;
reference symbols: Effect.gen, grokCredentialsPath, removeFallback,
runCommandExitCode, fs.remove.
- Around line 53-64: The Dockerfile generator renderGrokDockerfile currently
installs grok-dev using an undetermined tag ("grok-dev@latest --force"), making
builds non-deterministic; change the npm install line inside
renderGrokDockerfile to pin a specific released version (e.g.
"grok-dev@<MAJOR.MINOR.PATCH>") and remove the --force flag so the image is
reproducible and predictable, then update any docs/tests that expect the
previous behavior to use the pinned version.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c443bed7-adae-4577-8a81-848ac4778a6a

📥 Commits

Reviewing files that changed from the base of the PR and between d4d0fe9 and d3238f4.

📒 Files selected for processing (19)
  • packages/api/src/api/schema.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/api/src/http.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/app/src/web/api.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/web/api.ts
  • packages/api/src/services/auth-terminal-sessions.ts
  • packages/api/src/auth-terminal-runner.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/api/src/http.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/web/api-auth-schema.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
🔇 Additional comments (26)
packages/app/src/lib/core/templates-entrypoint/grok.ts (1)

1-279: LGTM!

packages/app/src/lib/core/templates/dockerfile.ts (1)

91-91: LGTM!

Also applies to: 121-123, 363-364

packages/lib/src/core/templates/dockerfile.ts (1)

91-91: LGTM!

Also applies to: 121-123, 363-364

packages/app/src/lib/usecases/auth-grok-oauth.ts (3)

38-44: Env-переменные NO_BROWSER и GROK_NO_BROWSER не документированы в Grok CLI.

Согласно официальной документации, Grok CLI не поддерживает эти переменные окружения для отключения автоматического открытия браузера. Браузер будет открываться при выполнении grok login, что может противоречить ожидаемому поведению URL handoff.

Проверьте актуальную документацию grok-dev или используйте альтернативный подход (CLI флаг --no-browser, если существует).

Does grok-dev npm package CLI support NO_BROWSER or --no-browser flag for OAuth login?

79-108: Скрипт исправления прав теперь использует безопасные разрешения.

Предыдущая проблема с chmod 777 исправлена: теперь используется chown -R 1000:1000, chmod 700 для директорий и chmod 600 для файлов.


1-37: LGTM!

Also applies to: 45-78, 109-137

packages/lib/src/usecases/auth-grok-oauth.ts (2)

38-44: Env-переменные NO_BROWSER и GROK_NO_BROWSER не документированы.

Аналогичная проблема как в packages/app: эти переменные окружения не задокументированы в Grok CLI.


1-37: LGTM!

Also applies to: 45-137

packages/app/src/lib/usecases/auth-grok-helpers.ts (1)

1-52: LGTM!

Also applies to: 66-115, 139-197, 224-272

packages/app/src/lib/usecases/auth-grok.ts (1)

1-95: LGTM!

packages/lib/src/usecases/auth-grok-helpers.ts (1)

1-52: LGTM!

Also applies to: 65-202, 219-270

packages/lib/src/usecases/auth-grok.ts (1)

1-95: LGTM!

packages/lib/tests/core/templates.test.ts (1)

30-30: LGTM!

Also applies to: 421-465, 486-498, 500-528

packages/app/src/web/api.ts (1)

184-195: LGTM!

packages/lib/src/core/templates-entrypoint/grok.ts (6)

13-25: LGTM!


27-121: LGTM!


122-143: LGTM!


144-188: LGTM!


189-257: LGTM!


258-278: LGTM!

packages/api/src/api/schema.ts (1)

35-36: LGTM!

Also applies to: 63-65, 68-68, 112-114, 122-122, 134-135, 250-250

packages/api/src/http.ts (1)

182-185: LGTM!

packages/api/src/services/auth-terminal-sessions.ts (1)

3-3: LGTM!

Also applies to: 72-77

packages/api/src/auth-terminal-runner.ts (1)

2-2: LGTM!

Also applies to: 5-13, 37-43

packages/api/src/services/project-auth.ts (1)

20-20: LGTM!

Also applies to: 30-30, 175-176, 185-185, 188-188, 191-191, 224-224, 261-280, 348-349, 351-351, 358-358, 363-363, 367-368, 384-385, 461-475

packages/app/src/web/api-auth-schema.ts (1)

26-39: LGTM!

Also applies to: 52-56

Comment thread packages/api/src/services/project-auth.ts Outdated
Comment thread packages/lib/tests/usecases/auth-grok.test.ts
Comment thread packages/lib/tests/usecases/auth-grok.test.ts
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 55f5789
Status: success
Files: 9 (16.81 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 176-185: The OAuth regex in grokUserSettingsCredentialMarkers uses
[^}]* which fails on nested objects; update the OAuth marker (or the detection
strategy in hasGrokUserSettingsCredentials) to handle nested content by
replacing the [^}]* with a non-greedy dot-all style pattern (e.g., [\s\S]*? )
or, better, parse the content as JSON and look up oauth keys
(apiKey|accessToken|access_token|authToken|refreshToken|refresh_token|token)
programmatically; adjust the grokUserSettingsCredentialMarkers array or the
detection flow to use the new pattern or JSON-based check so nested objects like
{"oauth":{"meta":{},"accessToken":"x"}} are correctly detected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 00b8b0ca-9dbb-42f1-98d9-bcda8b88b0e0

📥 Commits

Reviewing files that changed from the base of the PR and between d3238f4 and 55f5789.

📒 Files selected for processing (10)
  • packages/api/src/http.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/templates/dockerfile.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/http.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (36)
packages/lib/src/core/templates/dockerfile.ts (2)

91-91: LGTM!

Also applies to: 121-123


363-364: LGTM!

packages/app/src/lib/core/templates/dockerfile.ts (1)

91-91: LGTM!

Also applies to: 121-123, 363-364

packages/lib/tests/core/templates.test.ts (3)

30-30: LGTM!

Also applies to: 217-228


423-467: LGTM!


488-500: LGTM!

Also applies to: 502-529

packages/api/src/http.ts (2)

1-1: LGTM!

Also applies to: 184-184


429-465: LGTM!

packages/lib/tests/usecases/auth-grok.test.ts (3)

11-72: LGTM!


74-166: LGTM!


168-285: LGTM!

packages/app/src/lib/usecases/auth-grok.ts (2)

30-52: LGTM!


54-66: LGTM!

Also applies to: 73-98

packages/lib/src/usecases/auth-grok.ts (2)

30-52: LGTM!


54-66: LGTM!

Also applies to: 73-98

packages/api/src/services/project-auth.ts (5)

20-20: LGTM!

Also applies to: 30-30


173-197: LGTM!

Also applies to: 224-224


239-280: LGTM!


348-368: LGTM!


384-385: LGTM!

Also applies to: 461-475

packages/lib/src/usecases/auth-grok-helpers.ts (8)

158-184: 💤 Low value

Regex-паттерн для OAuth может не сработать при вложенных JSON-объектах.

Аналогично packages/app версии: паттерн [^}]* на линии 180 не обрабатывает вложенные объекты внутри oauth.


1-16: LGTM!


17-43: LGTM!


44-65: LGTM!


67-115: LGTM!


117-156: LGTM!


186-227: LGTM!


229-275: LGTM!

packages/app/src/lib/usecases/auth-grok-helpers.ts (8)

1-16: LGTM!


17-43: LGTM!


68-116: LGTM!


118-157: LGTM!


187-198: LGTM!


200-228: LGTM!


230-277: LGTM!


55-66: Версия grok-dev@1.1.7 существует и корректна.

Пакет опубликован 15 мая 2026 года и является актуальной стабильной версией. Использование точной версии вместо @latest соответствует требованиям к воспроизводимости.

Comment thread packages/app/src/lib/usecases/auth-grok-helpers.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 5455ccf
Status: success
Files: 9 (16.98 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 21e63e1
Status: success
Files: 9 (17.05 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 261-280: The current hasGrokAccountCredentials only checks for the
presence of `${accountPath}/.api-key` via hasFileAtPath and treats an empty file
as valid; change it to read and validate the file contents and only
succeed(true) when the trimmed contents are non-empty (consistent with
readGrokApiKey behavior). Concretely, inside hasGrokAccountCredentials replace
the hasFileAtPath branch with a readFile (or existing read helper) for
`${accountPath}/.api-key`, check that the result is a non-empty string after
trimming, return Effect.succeed(true) only then, and otherwise fall back to
hasApiKeyInEnvFile and hasGrokUserSettingsCredentials (or return false) to
preserve the existing flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fcf63705-5ecd-4438-99da-0c5d52b8681f

📥 Commits

Reviewing files that changed from the base of the PR and between 5455ccf and 21e63e1.

📒 Files selected for processing (4)
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: Test
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts

Comment thread packages/api/src/services/project-auth.ts
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 64ff87f
Status: success
Files: 9 (19.02 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
packages/api/src/services/project-auth.ts (1)

253-259: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Детектор oauth всё ещё может дать ложноположительный match.

[\s\S]*? после "oauth": { не ограничен границей объекта, поэтому regex спокойно перескакивает через } и подцепляет любой следующий "token": "..." ниже по файлу. В таком случае пустой oauth-блок будет засчитан как валидные Grok credentials, и ProjectGrokConnect сможет вернуть ложный success. Здесь нужен разбор JSON/точная проверка только внутри oauth, а не поиск по сырому тексту.

#!/bin/bash
python - <<'PY'
import re

pattern = re.compile(
    r'"oauth"\s*:\s*\{[\s\S]*?"(?:apiKey|accessToken|access_token|authToken|refreshToken|refresh_token|token)"\s*:\s*"[^"]+"'
)

sample = '{"oauth": {}, "telemetry": {"token": "abc"}}'
print("matches =", bool(pattern.search(sample)))
PY
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-auth.ts` around lines 253 - 259, The
current grokUserSettingsCredentialMarkers regex (used by ProjectGrokConnect) can
false-positive because the `"oauth"\s*:\s*\{[\s\S]*?` pattern is not confined to
the oauth object; change the detection to parse the user settings string as JSON
when possible and then explicitly inspect the oauth object for keys like apiKey,
accessToken, access_token, authToken, refreshToken, refresh_token, token (i.e.,
add a JSON-parse branch that checks typeof parsed.oauth === 'object' and checks
those properties), and only fall back to a conservative regex if parsing
fails—update references to grokUserSettingsCredentialMarkers and the
ProjectGrokConnect credential detection logic accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 481-484: The error text narrows remediation to only the CLI flow;
update the failure message in the Effect.fail call that uses missingSecret(...)
(invoked when matched === null) so it refers to neutral "Grok credentials" or
explicitly mentions both supported methods (".api-key file or GROK_API_KEY env")
instead of "Grok CLI login"; locate the call site where
hasGrokAccountCredentials() and missingSecret(...) are used (the Effect.flatMap
branch that currently calls upsertEnvKey(projectEnvText, projectGrokLabelKey,
normalizedLabel)) and replace the literal `"Grok CLI login"` with the
neutral/expanded text to cover both CLI and API-key login flows.

In `@packages/api/tests/project-auth.test.ts`:
- Around line 77-133: Add a fast-check property-based test around the existing
scenario: generate arbitrary strings (e.g., fc.string and fc.stringOf with
whitespace chars) and for each generated apiKey call the same setup/flow used in
the test (use withTempDir, buildProjectDetails, create grokDefaultAuth and write
the generated apiKey to ".api-key", then import the service and call
service.runProjectAuthFlow with flow "ProjectGrokConnect" and label "default").
Assert the invariant: if apiKey.trim().length === 0 then the result flips to an
ApiBadRequestError and envProjectPath does not contain
"GROK_AUTH_LABEL=default"; if apiKey.trim().length > 0 then the flow succeeds,
snapshot.activeGrokLabel === "default" and envProjectPath contains
"GROK_AUTH_LABEL=default". Use fc.property(...) and appropriate preconditions to
cover whitespace-only and non-empty cases.

In `@scripts/e2e/browser-command.sh`:
- Around line 24-25: The export lines for DOCKER_GIT_API_PORT and
DOCKER_GIT_WEB_PORT are hiding dg_pick_free_port failures; change to first
assign the result of dg_pick_free_port to a local variable (e.g.
api_port="$(dg_pick_free_port 34000 34999)"), test the command exit status and
that the value is non-empty, exit with a clear error message on failure, and
only then export DOCKER_GIT_API_PORT="$api_port" (repeat similarly for
dg_pick_free_port 41000 41999 -> DOCKER_GIT_WEB_PORT); reference the symbols
DOCKER_GIT_API_PORT, DOCKER_GIT_WEB_PORT and dg_pick_free_port when locating the
changes.

In `@scripts/e2e/opencode-autoconnect.sh`:
- Line 27: The current combined export masks failures from dg_pick_free_port;
change to first capture the value with DOCKER_GIT_API_PORT="$(dg_pick_free_port
34000 34999)", then immediately check the command’s success and result (e.g. if
[ $? -ne 0 ] || [ -z "$DOCKER_GIT_API_PORT" ]; then printf 'Failed to pick free
port\n' >&2; exit 1; fi), and only then run export DOCKER_GIT_API_PORT so
dg_pick_free_port errors are detected and handled properly.

---

Duplicate comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 253-259: The current grokUserSettingsCredentialMarkers regex (used
by ProjectGrokConnect) can false-positive because the `"oauth"\s*:\s*\{[\s\S]*?`
pattern is not confined to the oauth object; change the detection to parse the
user settings string as JSON when possible and then explicitly inspect the oauth
object for keys like apiKey, accessToken, access_token, authToken, refreshToken,
refresh_token, token (i.e., add a JSON-parse branch that checks typeof
parsed.oauth === 'object' and checks those properties), and only fall back to a
conservative regex if parsing fails—update references to
grokUserSettingsCredentialMarkers and the ProjectGrokConnect credential
detection logic accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c713abf2-9770-478c-97b4-b40b5ea2005b

📥 Commits

Reviewing files that changed from the base of the PR and between 21e63e1 and 64ff87f.

📒 Files selected for processing (9)
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • scripts/e2e/clone-auto-open-ssh.sh
  • scripts/e2e/clone-cache.sh
  • scripts/e2e/login-context.sh
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/runtime-volumes-ssh.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/clone-cache.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/login-context.sh
  • scripts/e2e/clone-auto-open-ssh.sh
  • scripts/e2e/runtime-volumes-ssh.sh
  • scripts/e2e/opencode-autoconnect.sh
  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/clone-cache.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/login-context.sh
  • scripts/e2e/clone-auto-open-ssh.sh
  • scripts/e2e/runtime-volumes-ssh.sh
  • scripts/e2e/opencode-autoconnect.sh
  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/clone-cache.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/login-context.sh
  • scripts/e2e/clone-auto-open-ssh.sh
  • scripts/e2e/runtime-volumes-ssh.sh
  • scripts/e2e/opencode-autoconnect.sh
  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/clone-cache.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/login-context.sh
  • scripts/e2e/clone-auto-open-ssh.sh
  • scripts/e2e/runtime-volumes-ssh.sh
  • scripts/e2e/opencode-autoconnect.sh
  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/api/tests/project-auth.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/api/tests/project-auth.test.ts
  • packages/api/src/services/project-auth.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/api/tests/project-auth.test.ts
🪛 Shellcheck (0.11.0)
scripts/e2e/browser-command.sh

[warning] 24-24: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 25-25: Declare and assign separately to avoid masking return values.

(SC2155)

scripts/e2e/opencode-autoconnect.sh

[warning] 27-27: Declare and assign separately to avoid masking return values.

(SC2155)

Comment thread packages/api/src/services/project-auth.ts
Comment thread packages/api/tests/project-auth.test.ts
Comment thread scripts/e2e/browser-command.sh Outdated
Comment thread scripts/e2e/opencode-autoconnect.sh Outdated
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 94a075f
Status: success
Files: 9 (19.68 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (4)
packages/app/src/lib/usecases/auth-grok-oauth.ts (1)

38-43: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Проверьте, что NO_BROWSER/GROK_NO_BROWSER реально поддерживаются текущим Grok CLI.

На Line 40–41 используются env-переменные, которые могут быть недокументированы для нужной версии CLI; если они игнорируются, flow “paste callback URL” может работать не так, как ожидается.

Для официального Grok CLI (x.ai installer, версия 0.1.211) поддерживаются ли переменные окружения NO_BROWSER или GROK_NO_BROWSER для отключения авто-открытия браузера в `grok login`? Если нет, какой документированный флаг/механизм используется вместо этого?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/auth-grok-oauth.ts` around lines 38 - 43, The
env array in usecases/auth-grok-oauth.ts currently sets NO_BROWSER and
GROK_NO_BROWSER which may not be supported by the Grok CLI; verify whether the
official Grok CLI for your target version supports those env vars and, if not,
switch to the documented mechanism (e.g., the CLI flag such as --no-browser or
the official login flow flag) when invoking the Grok process in the code that
builds the child process command, and add a fallback: detect CLI version/output
and if env vars are ignored, pass the documented flag or drive the “paste
callback URL” flow programmatically (capture stdout/stderr and feed stdin) so
the auth flow behaves deterministically.
packages/api/tests/project-auth.test.ts (1)

77-168: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Добавьте property-based проверку инварианта для Grok API key.

На Line 77–168 сейчас покрыты только несколько примерных входов; инвариант trim(apiKey).length === 0/> 0 лучше зафиксировать через fc.property, иначе остаётся неполное покрытие граничных случаев.

As per coding guidelines, "**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/tests/project-auth.test.ts` around lines 77 - 168, Add a
property-based test around the Grok API key trimming invariant: use fast-check's
fc.property to generate diverse apiKey strings (including whitespace-only and
non-empty-with-whitespace cases), write them to path.join(grokDefaultAuth,
".api-key") via fs.writeFileString, then call
service.runProjectAuthFlow(project, { flow: "ProjectGrokConnect", label:
"default" }) and assert the invariant—if trimmed apiKey length === 0 expect an
ApiBadRequestError and that fs.readFileString(envProjectPath) does not contain
"GROK_AUTH_LABEL=default", otherwise expect success (snapshot.activeGrokLabel
=== "default" and env contains the label); place this alongside or replacing the
current example cases in the it.effect test and reuse withTempDir,
withProjectsRoot, fs, path, and service helpers shown in the diff.
packages/lib/src/usecases/auth-grok-oauth.ts (1)

38-43: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Синхронизируйте с документированным способом headless OAuth для Grok CLI.

На Line 40–41 используются потенциально неподдерживаемые env-переменные; для shared-слоя лучше закрепить только официально подтверждённый механизм, иначе поведение будет зависеть от версии CLI.

Какие официальные параметры (env или CLI flags) у Grok CLI управляют browser auto-open в `grok login` в версиях, устанавливаемых через https://x.ai/cli/install.sh?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok-oauth.ts` around lines 38 - 43, The env
array in usecases/auth-grok-oauth.ts currently sets unverified variables
("NO_BROWSER" and "GROK_NO_BROWSER") which may not be supported by the Grok CLI;
remove these unsupported entries and replace them with the officially documented
headless-login mechanism (either the documented environment variable or CLI
flag) used by the Grok installer builds. Locate the env array in the
auth-grok-oauth module (where env: [...] is defined) and update it to only
include the officially supported key/value or add the documented CLI flag to the
grok login invocation after consulting the Grok CLI docs/installer
(https://x.ai/cli/install.sh) so the code uses the canonical headless option
rather than fragile, unofficial variables.
packages/api/src/services/project-auth.ts (1)

509-512: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Текст ошибки не отражает все поддерживаемые способы авторизации.

hasGrokAccountCredentials() проверяет как .api-key, так и GROK_API_KEY из .env, но при отсутствии credentials ошибка возвращает только "Grok CLI login". Это может направить пользователя на неверную remediation-ветку, хотя по ТЗ API-key login также first-class.

💡 Предлагаемое исправление
-                ? Effect.fail(missingSecret("Grok CLI login", normalizedLabel, grokAuthRoot))
+                ? Effect.fail(missingSecret("Grok credentials", normalizedLabel, grokAuthRoot))

As per coding guidelines, "Сверь изменения с исходным ТЗ/спекой ... флагай любой уход от спеки".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/src/services/project-auth.ts` around lines 509 - 512, The error
message passed to missingSecret currently says "Grok CLI login" but
hasGrokAccountCredentials() actually checks both the CLI login and API-key
(e.g., .api-key file or GROK_API_KEY), so update the failure message in the
Effect.flatMap branch (where missingSecret is called with "Grok CLI login",
normalizedLabel, grokAuthRoot) to mention both supported auth methods (for
example "Grok CLI login or API key") so users are routed to the correct
remediation path; keep the rest of the upsertEnvKey call (projectEnvText,
projectGrokLabelKey, normalizedLabel) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-status.ts`:
- Around line 25-29: The current branching on authMethod using an if/else is
non-exhaustive; replace it with an exhaustive pattern match via
Match.match(authMethod).exhaustive() (or authMethod.Match.exhaustive() according
to your Effect API) so every union case is handled; inside each branch emit the
appropriate Effect.log (e.g., the "none" case logs "Grok not connected" and
other cases log "Grok connected" with accountLabel and authMethod) and remove
the ad-hoc if/return to satisfy the union-exhaustiveness rule.

In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 124-136: The current successive if blocks using
grokDeploymentKeyDefaultExpansion, grokApiKeyDefaultExpansion, and
xaiApiKeyDefaultExpansion overwrite each other so the final exported key ends up
being the last non-empty check (XAI); choose a clear behavior and implement it:
either (A) enforce a documented priority by turning the three independent ifs
into an ordered if/elif chain that sets GROK_API_KEY, GROK_DEPLOYMENT_KEY, and
XAI_API_KEY only from the highest-priority non-empty expansion, or (B) resolve a
single shared value (e.g., resolvedKey = first non-empty of
grokDeploymentKeyDefaultExpansion, grokApiKeyDefaultExpansion,
xaiApiKeyDefaultExpansion or the file-derived value) and export GROK_API_KEY,
GROK_DEPLOYMENT_KEY, and XAI_API_KEY all to that resolved value; update the
block around
grokDeploymentKeyDefaultExpansion/grokApiKeyDefaultExpansion/xaiApiKeyDefaultExpansion
accordingly and add a short comment describing the chosen priority/behavior.

In `@packages/lib/src/core/templates/dockerfile.ts`:
- Around line 125-133: The Dockerfile currently downloads and executes the
remote installer referenced by grokCliInstallScriptUrl into /tmp/grok-install.sh
without integrity checks; change the RUN step to first download the script to
/tmp/grok-install.sh, compute its SHA256 (e.g., sha256sum /tmp/grok-install.sh),
compare that checksum against a pinned value injected by the template (add a
GROK_INSTALL_SHA256 or similar template variable), and exit non‑zero if it
doesn't match; only after successful verification, run
HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash
/tmp/grok-install.sh ${grokCliVersion} and proceed with the existing install/mv
cleanup steps.

In `@packages/lib/src/usecases/auth-grok-status.ts`:
- Around line 25-29: Replace the partial if-check on authMethod with an
exhaustive pattern match using Match.exhaustive() (or .exhaustive()) so all
possible authMethod union cases are handled; specifically, change the logic
around the `authMethod` variable in the `auth-grok-status` flow to use
Match.exhaustive(authMethod) and produce the appropriate Effect.log messages
(e.g., for "none" log "Grok not connected (accountLabel)" and for other cases
log "Grok connected (accountLabel, authMethod)"), and ensure any new authMethod
variants get explicit branches rather than falling through.

---

Duplicate comments:
In `@packages/api/src/services/project-auth.ts`:
- Around line 509-512: The error message passed to missingSecret currently says
"Grok CLI login" but hasGrokAccountCredentials() actually checks both the CLI
login and API-key (e.g., .api-key file or GROK_API_KEY), so update the failure
message in the Effect.flatMap branch (where missingSecret is called with "Grok
CLI login", normalizedLabel, grokAuthRoot) to mention both supported auth
methods (for example "Grok CLI login or API key") so users are routed to the
correct remediation path; keep the rest of the upsertEnvKey call
(projectEnvText, projectGrokLabelKey, normalizedLabel) unchanged.

In `@packages/api/tests/project-auth.test.ts`:
- Around line 77-168: Add a property-based test around the Grok API key trimming
invariant: use fast-check's fc.property to generate diverse apiKey strings
(including whitespace-only and non-empty-with-whitespace cases), write them to
path.join(grokDefaultAuth, ".api-key") via fs.writeFileString, then call
service.runProjectAuthFlow(project, { flow: "ProjectGrokConnect", label:
"default" }) and assert the invariant—if trimmed apiKey length === 0 expect an
ApiBadRequestError and that fs.readFileString(envProjectPath) does not contain
"GROK_AUTH_LABEL=default", otherwise expect success (snapshot.activeGrokLabel
=== "default" and env contains the label); place this alongside or replacing the
current example cases in the it.effect test and reuse withTempDir,
withProjectsRoot, fs, path, and service helpers shown in the diff.

In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 38-43: The env array in usecases/auth-grok-oauth.ts currently sets
NO_BROWSER and GROK_NO_BROWSER which may not be supported by the Grok CLI;
verify whether the official Grok CLI for your target version supports those env
vars and, if not, switch to the documented mechanism (e.g., the CLI flag such as
--no-browser or the official login flow flag) when invoking the Grok process in
the code that builds the child process command, and add a fallback: detect CLI
version/output and if env vars are ignored, pass the documented flag or drive
the “paste callback URL” flow programmatically (capture stdout/stderr and feed
stdin) so the auth flow behaves deterministically.

In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 38-43: The env array in usecases/auth-grok-oauth.ts currently sets
unverified variables ("NO_BROWSER" and "GROK_NO_BROWSER") which may not be
supported by the Grok CLI; remove these unsupported entries and replace them
with the officially documented headless-login mechanism (either the documented
environment variable or CLI flag) used by the Grok installer builds. Locate the
env array in the auth-grok-oauth module (where env: [...] is defined) and update
it to only include the officially supported key/value or add the documented CLI
flag to the grok login invocation after consulting the Grok CLI docs/installer
(https://x.ai/cli/install.sh) so the code uses the canonical headless option
rather than fragile, unofficial variables.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 40722653-ddf0-453a-aa33-addd5bbfb38f

📥 Commits

Reviewing files that changed from the base of the PR and between 64ff87f and 94a075f.

📒 Files selected for processing (22)
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/core/auth-domain.ts
  • packages/lib/src/usecases/auth-grok-logout.ts
  • packages/app/src/docker-git/frontend-lib/core/auth-domain.ts
  • packages/app/src/lib/usecases/auth-grok-logout.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/docker-git/cli/parser-auth.ts
  • packages/app/src/lib/core/templates/dockerfile.ts
  • packages/app/src/lib/core/auth-domain.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/app/src/lib/usecases/auth-grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/lib/src/usecases/auth-grok.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/api/tests/project-auth.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/api/tests/project-auth.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (23)
packages/lib/src/core/auth-domain.ts (1)

109-137: LGTM!

Also applies to: 155-157

packages/lib/src/usecases/auth-grok-logout.ts (1)

21-35: LGTM!

packages/app/src/docker-git/frontend-lib/core/auth-domain.ts (1)

110-137: LGTM!

Also applies to: 156-158

packages/app/src/lib/usecases/auth-grok-logout.ts (1)

21-35: LGTM!

packages/app/src/docker-git/cli/parser-auth.ts (1)

14-15: LGTM!

Also applies to: 47-47, 54-54, 197-229, 244-244

packages/app/src/lib/core/templates/dockerfile.ts (1)

126-127: ⚡ Quick win

Поставка Grok CLI несёт риск supply-chain, но предложенное исправление не осуществимо.

На Lines 126-127 выполняется удалённый скрипт без проверки целостности. Однако xAI не публикует официальные SHA256-контрольные суммы или immutable версионные URL для install.sh [веб-поиск 18.05.2026]. Предложенное в diff добавление SHA256-константы не имеет источника и не может быть реализовано без прямого участия xAI.

Что можно сделать вместо этого:

  • Свяжитесь с xAI и попросите опубликовать хеш-суммы для releases (или подпишите скрипт/release в формате cosign/minisign).
  • Если xAI не поддерживает это, рассмотрите зеркалирование/vendoring скрипта в репозитории с явной версией вместо загрузки из интернета на build-time.
  • Текущий подход (скачивание в файл перед выполнением, а не piping) лучше, чем рекомендуемый xAI метод, и обеспечивает возможность локальной проверки.
packages/lib/src/core/templates-entrypoint/grok.ts (3)

1-27: LGTM!


140-182: LGTM!


183-298: LGTM!

packages/api/src/services/project-auth.ts (4)

20-32: LGTM!


174-198: LGTM!

Also applies to: 239-239


200-322: LGTM!


382-414: LGTM!

packages/lib/src/usecases/auth-grok.ts (3)

30-52: LGTM!


54-66: LGTM!


73-95: LGTM!

packages/app/src/lib/usecases/auth-grok-helpers.ts (5)

1-46: LGTM!


58-74: LGTM!


97-224: LGTM!


226-255: LGTM!


256-304: LGTM!

packages/lib/src/usecases/auth-grok-helpers.ts (1)

1-303: LGTM!

packages/app/src/lib/core/templates-entrypoint/grok.ts (1)

1-300: LGTM!

Comment thread packages/app/src/lib/usecases/auth-grok-status.ts Outdated
Comment thread packages/lib/src/core/templates-entrypoint/grok.ts Outdated
Comment on lines +125 to +133
RUN set -eu; \
curl -fsSL --retry 5 --retry-all-errors --retry-delay 2 ${grokCliInstallScriptUrl} -o /tmp/grok-install.sh; \
HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion}; \
install -m 0755 "$(readlink -f /usr/local/bin/grok)" /usr/local/bin/grok.real; \
install -m 0755 "$(readlink -f /usr/local/bin/agent)" /usr/local/bin/agent.real; \
mv -f /usr/local/bin/grok.real /usr/local/bin/grok; \
mv -f /usr/local/bin/agent.real /usr/local/bin/agent; \
rm -rf /tmp/grok-install.sh /tmp/grok-install-home
RUN grok --version`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не исполняйте удалённый install.sh без проверки целостности.

На Line 126–127 скрипт с x.ai скачивается и сразу запускается. Добавьте pinned checksum (или signature verification), иначе это supply-chain риск.

Возможный минимальный фикс
+ARG GROK_INSTALL_SHA256=<pin-this>
 RUN set -eu; \
   curl -fsSL --retry 5 --retry-all-errors --retry-delay 2 ${grokCliInstallScriptUrl} -o /tmp/grok-install.sh; \
+  echo "${GROK_INSTALL_SHA256}  /tmp/grok-install.sh" | sha256sum -c -; \
   HOME=/tmp/grok-install-home GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion}; \
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/core/templates/dockerfile.ts` around lines 125 - 133, The
Dockerfile currently downloads and executes the remote installer referenced by
grokCliInstallScriptUrl into /tmp/grok-install.sh without integrity checks;
change the RUN step to first download the script to /tmp/grok-install.sh,
compute its SHA256 (e.g., sha256sum /tmp/grok-install.sh), compare that checksum
against a pinned value injected by the template (add a GROK_INSTALL_SHA256 or
similar template variable), and exit non‑zero if it doesn't match; only after
successful verification, run HOME=/tmp/grok-install-home
GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh ${grokCliVersion} and
proceed with the existing install/mv cleanup steps.

Comment thread packages/lib/src/usecases/auth-grok-status.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 2a1eded
Status: success
Files: 10 (22.29 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

@skulidropek skulidropek force-pushed the issue-304-3b5ced26375c branch from 2a1eded to 12059aa Compare May 18, 2026 07:00
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 12059aa
Status: success
Files: 10 (22.50 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 183-184: Replace the hardcoded chown "1000:1000" with the
configured SSH user ownership: read the owner from config.sshUser (e.g.,
config.sshUser.uid and config.sshUser.gid) and use those values when running
chown on GROK_SETTINGS_DIR (and keep the chmod for GROK_CONFIG_SETTINGS_FILE and
GROK_USER_SETTINGS_FILE); if config.sshUser is not present, fall back to the
runtime user IDs (e.g., id -u/id -g) to avoid breaking permissions in rootless
or remapped containers.

In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 185-190: Функция renderGrokSudoConfig создаёт sudo-файл с опасной
записью "${config.sshUser} ALL=(ALL) NOPASSWD:ALL"; ограничьте привилегии либо
перечислением конкретных необходимых команд вместо NOPASSWD:ALL (например только
/usr/bin/systemctl, /usr/bin/journalctl или скрипты агента) с явным указанием
пути, либо, если полный безпарольный sudo — это осознанное решение, добавьте в
renderGrokSudoConfig/рядом с шаблоном комментарий, объясняющий
причинно-следственную обоснованность и риск-обоснование для config.sshUser в
TemplateConfig, чтобы ревью явно видел выбор.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 208e2981-82ab-4a57-b62e-a8aee628acb0

📥 Commits

Reviewing files that changed from the base of the PR and between 94a075f and 2a1eded.

📒 Files selected for processing (17)
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Browser command)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/lib/src/usecases/auth-grok-status.ts
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/tests/project-auth.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/api/tests/project-auth.test.ts
🔇 Additional comments (24)
packages/lib/src/usecases/auth-grok-status.ts (1)

1-33: LGTM!

scripts/e2e/opencode-autoconnect.sh (1)

22-22: LGTM!

Also applies to: 27-28

scripts/e2e/_lib.sh (1)

137-202: LGTM!

scripts/e2e/browser-command.sh (1)

24-27: LGTM!

packages/app/src/lib/usecases/auth-grok-credential-text.ts (1)

1-77: LGTM!

packages/lib/src/usecases/auth-grok-credential-text.ts (1)

1-75: LGTM!

packages/app/src/lib/usecases/auth-grok-status.ts (1)

1-33: LGTM!

packages/app/src/lib/usecases/auth-grok-oauth.ts (1)

1-135: LGTM!

packages/lib/src/usecases/auth-grok-oauth.ts (3)

44-65: Отсутствует TSDoc для экспортируемой функции buildDockerGrokAuthArgs.

Согласно coding guidelines, все экспортируемые функции должны иметь TSDoc с @pure, @effect, @invariant, @precondition, @postcondition, @complexity.


108-135: Отсутствует TSDoc для экспортируемой функции runGrokOauthLoginWithPrompt.

Согласно coding guidelines, все экспортируемые функции должны иметь TSDoc с @pure, @effect, @invariant, @precondition, @postcondition, @complexity.


77-106: LGTM!

packages/lib/src/core/templates-entrypoint/grok.ts (2)

1-12: LGTM!

Also applies to: 281-300


111-140: LGTM!

packages/lib/tests/usecases/auth-grok.test.ts (1)

83-108: LGTM!

Also applies to: 109-159, 160-200, 202-261, 262-276, 278-291, 293-312, 314-333, 335-371, 373-416

packages/lib/tests/core/templates.test.ts (1)

30-30: LGTM!

Also applies to: 218-229, 424-468, 489-508, 510-538

packages/api/src/services/project-auth.ts (1)

21-33: LGTM!

Also applies to: 175-199, 201-213, 255-309, 369-401, 403-416, 490-504

packages/api/tests/project-auth.test.ts (1)

1-127: LGTM!

Also applies to: 129-162, 164-321

packages/app/src/lib/usecases/auth-grok-helpers.ts (1)

1-75: LGTM!

Also applies to: 98-125, 127-169, 171-206, 208-236, 237-285

packages/lib/src/usecases/auth-grok-helpers.ts (1)

1-74: LGTM!

Also applies to: 76-124, 126-168, 170-205, 207-235, 237-283

packages/app/src/lib/core/templates-entrypoint/grok.ts (5)

275-275: Тот же захардкоженный UID 1000.

Аналогичная проблема с chown 1000:1000 — см. комментарий выше (строка 183).


1-28: LGTM!


29-147: LGTM!


282-302: LGTM!


186-191: ⚡ Quick win

Валидация config.sshUser защищена на достаточном уровне и не требует дополнительных мер.

Функция parseSshUser в command-builders-shared.ts обязательно валидирует входное значение против регулярного выражения /^[a-z_][a-z0-9_-]{0,31}$/, которое математически исключает все shell-метасимволы, включая символы новой строки. Попытки внедрить произвольные sudoers-правила вроде "user\nroot ALL=(ALL) NOPASSWD:ALL" отклоняются на этапе парсинга перед созданием TemplateConfig. В коде уже задокументирована FORMAT THEOREM, подтверждающая что любое значение, прошедшее isUnixUserName, не содержит опасных символов.

Comment thread packages/app/src/lib/core/templates-entrypoint/grok.ts Outdated
Comment thread packages/lib/src/core/templates-entrypoint/grok.ts
# Conflicts:
#	packages/app/src/docker-git/cli/usage.ts
#	packages/lib/src/core/templates/docker-compose.ts
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 0f97fc1
Status: success
Files: 10 (22.71 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: b73a364
Status: success
Files: 10 (24.41 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/tests/project-auth.test.ts`:
- Around line 118-120: Remove the forbidden type assertion "as const" from the
objects returned by the Effect.match handlers (the onFailure and onSuccess
results) — e.g., change the returned {_tag: "failure" as const, ...} and {_tag:
"success" as const, ...} to plain {_tag: "failure", ...} and {_tag: "success",
...}; TypeScript will infer literal string types and existing narrowing logic
(used later in the test around the snapshot checks) will continue to work
without the cast.

In `@packages/app/src/docker-git/cli/usage.ts`:
- Line 79: Обновите весь блок help/usage в файле containing usage.ts так, чтобы
упоминания провайдеров аутентификации и секция "Авторизация"/"Auth providers"
включали Grok (Grok) повсеместно, и чтобы описание флага --auto (строка
"--auto[=claude|codex|gemini|grok") согласовывалось с этим: добавьте Grok в
список провайдеров, обновите пояснения выбора агента при --auto (как по
умолчанию при авторизации или при нескольких доступных) и приведите
примеры/текст секции "auth" и "Auth providers" к одному стилю с остальными
провайдерами (используйте те же формулировки и порядок, что для
claude|codex|gemini).

In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The grokAuthConfigTemplate uses direct expansions of
GROK_AUTH_LABEL (via GROK_LABEL_RAW="$GROK_AUTH_LABEL") which will fail under
set -u; update the template so GROK_LABEL_RAW is assigned with a safe default
expansion (e.g. use parameter expansion like "${GROK_AUTH_LABEL:-}" or
"${GROK_AUTH_LABEL:-default}") and keep the existing fallback logic for
GROK_LABEL_NORM; modify the occurrences inside the grokAuthConfigTemplate string
(referencing variable grokAuthConfigTemplate and the template variables
GROK_LABEL_RAW, GROK_AUTH_LABEL, GROK_LABEL_NORM, GROK_AUTH_ROOT) to use the
safe expansions so the bootstrap won’t abort when GROK_AUTH_LABEL is unset
(apply same fix for the other block at lines 193-211).

In `@packages/app/src/lib/usecases/auth-grok-helpers.ts`:
- Around line 215-220: The fallback uses raw accountPath in the docker -v mount
which can fail on some hosts; before building removeFallback (the pipe that
calls runCommandExitCode), compute the Docker-safe host path using the same
resolver used in the Grok OAuth flow (call it the Docker-safe host path resolver
used elsewhere) and store it in hostPath, then replace `${accountPath}` with
`${hostPath}` in the docker args so the container gets a normalized mount path.
Ensure you reference removeFallback, runCommandExitCode, and accountPath when
making this change.

In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The script reads GROK_AUTH_LABEL directly which breaks when
shell is run with set -u; change the direct reads to parameter-expansion
defaults (e.g., use GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" instead of
GROK_LABEL_RAW="$GROK_AUTH_LABEL") so unset variable access becomes safe, keep
the existing normalization in GROK_LABEL_NORM and fallback to "default" intact,
and apply the same defensive ${VAR:-} pattern to other occurrences of
GROK_AUTH_LABEL referenced later in the file (the block around GROK_LABEL_RAW,
GROK_LABEL_NORM and any uses in the 192-210 range).

In `@packages/lib/src/usecases/auth-grok-helpers.ts`:
- Around line 237-252: The defaults in defaultGrokProjectSettings and
defaultGrokUserSettings disable sandboxing and auto-trust the MCP server
(sandboxMode: "off", mcpServers.playwright.trust: true, and
confirmBeforeToolUse: false), which weakens security; update the code by adding
a concise inline comment and/or JSDoc above defaultGrokProjectSettings and
defaultGrokUserSettings that explains the security implications, notes these are
permissive defaults intended for dev/testing only, lists recommended safer
alternatives (e.g., sandboxMode: "on"/"strict", trust: false,
confirmBeforeToolUse: true) for production, and reference issue-304 for context
so readers see why these defaults exist and how to harden them.
- Around line 203-204: The variable name hasUserSettings is misleading because
it holds the result of hasGrokCredentials(fs, accountPath), which checks API key
and auth.json as well; rename the variable to hasGrokCredentials (or
hasCredentials) and update its usage in this function (the const declaration and
the ternary return that currently returns "oauth" or "none") so the name
reflects the actual semantic of the check and avoids confusion with
user-settings-only checks.

In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 83-106: fixGrokAuthPermissions currently swallows chmod/chown
failures by logging them then returning Effect.void, which makes the overall
auth step appear successful; change it so the effect fails instead of returning
success: in fixGrokAuthPermissions (the runCommandWithExitCodes pipeline that
can throw CommandFailedError), remove orElse(() => Effect.void) and either let
the original error propagate or map it to an AuthError (e.g.,
Effect.mapError(err => new AuthError({ cause: err }))) so callers see a failure
rather than a silent success.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2b1ede22-1cc7-4a96-a999-c7b73bc59fd8

📥 Commits

Reviewing files that changed from the base of the PR and between 2a1eded and 0f97fc1.

📒 Files selected for processing (33)
  • packages/api/src/api/contracts.ts
  • packages/api/src/api/schema.ts
  • packages/api/src/http.ts
  • packages/api/src/services/agents.ts
  • packages/api/src/services/project-auth.ts
  • packages/api/src/services/projects.ts
  • packages/api/tests/project-auth.test.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/app/src/docker-git/api-client.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/app/src/web/api.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/docker-git/api-client.ts
  • packages/lib/src/core/templates-entrypoint.ts
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/docker-git/api-client-create.ts
  • packages/api/src/services/projects.ts
  • packages/app/src/web/api.ts
  • packages/api/src/services/agents.ts
  • packages/lib/src/core/templates-entrypoint/base.ts
  • packages/app/src/docker-git/program-unsupported.ts
  • packages/app/src/lib/usecases/auth-grok-status.ts
  • packages/api/tests/projects.test.ts
  • scripts/e2e/browser-command.sh
  • scripts/e2e/opencode-autoconnect.sh
  • scripts/e2e/_lib.sh
  • packages/lib/src/usecases/auth-grok-status.ts
  • packages/lib/src/usecases/auth-grok-credential-text.ts
  • packages/api/src/http.ts
  • packages/app/src/lib/usecases/auth-grok-credential-text.ts
  • packages/api/src/api/schema.ts
  • packages/lib/src/core/templates/dockerfile.ts
  • packages/lib/src/usecases/auth-sync-helpers.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/src/core/templates/docker-compose.ts
  • packages/api/src/api/contracts.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/usecases/auth-grok-helpers.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/api/src/services/project-auth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-helpers.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/api/tests/projects.test.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/api/tests/projects.test.ts
  • packages/api/tests/project-auth.test.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/lib/tests/usecases/auth-grok.test.ts
🔇 Additional comments (30)
packages/app/src/docker-git/api-client.ts (1)

261-261: LGTM!

packages/lib/src/core/templates-entrypoint.ts (1)

26-26: LGTM!

Also applies to: 67-67

packages/app/src/docker-git/api-client-create.ts (1)

50-51: LGTM!

packages/api/src/services/projects.ts (1)

441-442: LGTM!

packages/app/src/web/api.ts (1)

188-188: LGTM!

packages/api/src/services/agents.ts (1)

72-74: LGTM!

packages/lib/src/core/templates-entrypoint/base.ts (1)

27-27: LGTM!

packages/app/src/docker-git/program-unsupported.ts (1)

14-16: LGTM!

Also applies to: 57-68

packages/app/src/lib/usecases/auth-grok-status.ts (1)

19-33: LGTM!

packages/api/tests/projects.test.ts (1)

210-210: LGTM!

scripts/e2e/browser-command.sh (1)

24-27: LGTM!

scripts/e2e/opencode-autoconnect.sh (1)

22-22: LGTM!

Also applies to: 27-28

scripts/e2e/_lib.sh (1)

137-202: LGTM!

packages/lib/src/usecases/auth-grok-status.ts (1)

19-33: LGTM!

packages/lib/src/usecases/auth-grok-credential-text.ts (1)

1-47: LGTM!

packages/lib/src/core/templates/dockerfile.ts (1)

125-133: Исполнение удалённого install.sh всё ещё без проверки целостности.

Здесь всё ещё выполняется скачанный скрипт без pinned checksum/signature, поэтому supply-chain риск не закрыт.

packages/lib/src/core/templates/docker-compose.ts (1)

234-234: Смешаны разные env-фрагменты под одним комментарием.

Строка по-прежнему объединяет maybeGrokAuthLabelEnv с maybeAgentModeEnv/maybeAgentAutoEnv, из-за чего комментарий не соответствует всем переменным на строке.

packages/api/src/http.ts (1)

185-185: LGTM!

Also applies to: 430-466

packages/app/src/lib/usecases/auth-grok-credential-text.ts (1)

1-77: LGTM!

packages/api/src/api/schema.ts (1)

37-38: LGTM!

Also applies to: 65-67, 70-70, 114-117, 124-124, 136-138, 256-256

packages/lib/src/usecases/auth-sync-helpers.ts (1)

9-10: LGTM!

Also applies to: 118-126, 177-177

packages/app/src/lib/usecases/auth-grok-oauth.ts (1)

1-136: LGTM!

packages/lib/src/usecases/auth-grok-helpers.ts (8)

1-33: LGTM!


35-47: LGTM!


49-74: LGTM!


76-96: LGTM!


98-124: LGTM!


126-168: LGTM!


254-283: LGTM!


214-225: ⚡ Quick win

Путь защищён от path traversal атак на уровне нормализации label.

Хотя accountPath используется в Docker volume mount, рисков нет. Функция normalizeAccountLabel использует строгий regex /[^a-z0-9]+/g, который оставляет только буквы и цифры, переводя все остальные символы (включая .., /, .) в дефисы или удаляя их. Так, попытка path traversal вроде ../../../etc преобразуется в etcpasswd или подобное. Затем path.join(rootPath, sanitizedLabel) конкатенирует пути безопасно. Кроме того, аргументы Docker передаются массивом ["run", "--rm", "-v", "${accountPath}:/target", ...], а не через интерполяцию shell, поэтому command injection также невозможна.

			> Likely an incorrect or invalid review comment.

Comment on lines +118 to +120
onFailure: (error) => ({ _tag: "failure" as const, errorTag: error._tag }),
onSuccess: (snapshot) => ({ _tag: "success" as const, activeGrokLabel: snapshot.activeGrokLabel })
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

find . -name "project-auth.test.ts" -type f

Repository: ProverCoderAI/docker-git

Length of output: 110


🏁 Script executed:

sed -n '100,140p' ./packages/api/tests/project-auth.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 1450


🏁 Script executed:

head -50 ./packages/api/tests/project-auth.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 1774


🏁 Script executed:

sed -n '118,160p' ./packages/api/tests/project-auth.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 1717


🏁 Script executed:

grep -n "as const\|as " ./packages/api/tests/project-auth.test.ts | head -20

Repository: ProverCoderAI/docker-git

Length of output: 423


Удалите as const из результатов Effect.match.

Согласно coding guidelines, type casting с as запрещен в регулярном коде. В этом случае as const является избыточным: TypeScript автоматически выводит литеральные типы для строковых литералов в объектах. Тип narrowing на линиях 141-153 работает корректно без этих каст.

Рекомендуемое исправление
-            onFailure: (error) => ({ _tag: "failure" as const, errorTag: error._tag }),
-            onSuccess: (snapshot) => ({ _tag: "success" as const, activeGrokLabel: snapshot.activeGrokLabel })
+            onFailure: (error) => ({ _tag: "failure", errorTag: error._tag }),
+            onSuccess: (snapshot) => ({ _tag: "success", activeGrokLabel: snapshot.activeGrokLabel })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/tests/project-auth.test.ts` around lines 118 - 120, Remove the
forbidden type assertion "as const" from the objects returned by the
Effect.match handlers (the onFailure and onSuccess results) — e.g., change the
returned {_tag: "failure" as const, ...} and {_tag: "success" as const, ...} to
plain {_tag: "failure", ...} and {_tag: "success", ...}; TypeScript will infer
literal string types and existing narrowing logic (used later in the test around
the snapshot checks) will continue to work without the cast.

Comment thread packages/app/src/docker-git/cli/usage.ts
Comment thread packages/app/src/lib/core/templates-entrypoint/grok.ts
Comment on lines +215 to +220
const removeFallback = pipe(
runCommandExitCode({
cwd,
command: "docker",
args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]
}),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Нормализуйте host path перед docker run fallback.

В этой recovery-ветке в -v уходит raw accountPath, хотя в OAuth flow вы уже используете отдельный resolver для Docker-safe host path. Если fs.remove() упадёт на платформе/пути, который Docker не умеет монтировать напрямую, fallback тоже не сработает, и старый .grok останется на месте.

💡 Минимальная правка
-        args: ["run", "--rm", "-v", `${accountPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]
+        args: ["run", "--rm", "-v", `${hostPath}:/target`, "alpine", "rm", "-rf", "/target/.grok"]

Перед этим получите hostPath тем же способом, что уже используется в Grok OAuth flow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/usecases/auth-grok-helpers.ts` around lines 215 - 220,
The fallback uses raw accountPath in the docker -v mount which can fail on some
hosts; before building removeFallback (the pipe that calls runCommandExitCode),
compute the Docker-safe host path using the same resolver used in the Grok OAuth
flow (call it the Docker-safe host path resolver used elsewhere) and store it in
hostPath, then replace `${accountPath}` with `${hostPath}` in the docker args so
the container gets a normalized mount path. Ensure you reference removeFallback,
runCommandExitCode, and accountPath when making this change.

Comment thread packages/lib/src/core/templates-entrypoint/grok.ts
Comment on lines +203 to +204
const hasUserSettings = yield* _(hasGrokCredentials(fs, accountPath))
return hasUserSettings ? "oauth" : "none"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Вводящее в заблуждение имя переменной.

Переменная hasUserSettings содержит результат hasGrokCredentials(), которая проверяет не только user-settings, но также apiKey и auth.json. Имя переменной не отражает фактическую семантику.

♻️ Предлагаемое исправление
-    const hasUserSettings = yield* _(hasGrokCredentials(fs, accountPath))
-    return hasUserSettings ? "oauth" : "none"
+    const hasCredentials = yield* _(hasGrokCredentials(fs, accountPath))
+    return hasCredentials ? "oauth" : "none"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 203 - 204, The
variable name hasUserSettings is misleading because it holds the result of
hasGrokCredentials(fs, accountPath), which checks API key and auth.json as well;
rename the variable to hasGrokCredentials (or hasCredentials) and update its
usage in this function (the const declaration and the ternary return that
currently returns "oauth" or "none") so the name reflects the actual semantic of
the check and avoids confusion with user-settings-only checks.

Comment on lines +237 to +252
export const defaultGrokProjectSettings = {
sandboxMode: "off",
mcpServers: {
playwright: {
command: "docker-git-playwright-mcp",
args: [],
trust: true
}
}
}

export const defaultGrokUserSettings = (apiKey: string | null) => ({
...(apiKey === null ? {} : { apiKey }),
sandboxMode: "off",
confirmBeforeToolUse: false
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Отключённый sandbox и trust: true снижают защиту — убедитесь, что это задокументировано.

Конфигурация по умолчанию отключает sandbox (sandboxMode: "off") и автоматически доверяет MCP-серверу (trust: true), а также отключает подтверждение перед использованием инструментов (confirmBeforeToolUse: false). Это соответствует спецификации issue-304, но пользователи должны понимать последствия для безопасности.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/src/usecases/auth-grok-helpers.ts` around lines 237 - 252, The
defaults in defaultGrokProjectSettings and defaultGrokUserSettings disable
sandboxing and auto-trust the MCP server (sandboxMode: "off",
mcpServers.playwright.trust: true, and confirmBeforeToolUse: false), which
weakens security; update the code by adding a concise inline comment and/or
JSDoc above defaultGrokProjectSettings and defaultGrokUserSettings that explains
the security implications, notes these are permissive defaults intended for
dev/testing only, lists recommended safer alternatives (e.g., sandboxMode:
"on"/"strict", trust: false, confirmBeforeToolUse: true) for production, and
reference issue-304 for context so readers see why these defaults exist and how
to harden them.

Comment thread packages/lib/src/usecases/auth-grok-oauth.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (1)
packages/app/src/lib/core/templates-entrypoint/grok.ts (1)

29-45: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

GROK_AUTH_LABEL всё ещё падает под set -u.

Первое же чтение GROK_LABEL_RAW="$GROK_AUTH_LABEL" аварийно завершает bootstrap до fallback на default, а ниже тот же optional env снова читается при генерации profile/SSH env. В контейнере без явно выбранного label Grok setup не поднимется.

Предлагаемая правка
-GROK_LABEL_RAW="$GROK_AUTH_LABEL"
+GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}"
 if [[ -z "$GROK_LABEL_RAW" ]]; then
   GROK_LABEL_RAW="default"
 fi

 GROK_LABEL_NORM="$(printf "%s" "$GROK_LABEL_RAW" \
   | tr '[:upper:]' '[:lower:]' \
   | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')"
 if [[ -z "$GROK_LABEL_NORM" ]]; then
   GROK_LABEL_NORM="default"
 fi
+export GROK_AUTH_LABEL="$GROK_LABEL_NORM"

Also applies to: 199-217

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/lib/core/templates-entrypoint/grok.ts` around lines 29 - 45,
The template reads GROK_AUTH_LABEL directly which breaks under set -u; update
grokAuthConfigTemplate to safely reference the optional env using shell
parameter expansion (e.g. replace GROK_LABEL_RAW="$GROK_AUTH_LABEL" with
GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" and any other direct uses of
GROK_AUTH_LABEL later in the template/profile/SSH env generation with
${GROK_AUTH_LABEL:-} so the bootstrap won't abort and the existing fallback to
"default" via GROK_LABEL_NORM still applies); ensure changes are made inside the
grokAuthConfigTemplate string containing GROK_LABEL_RAW, GROK_LABEL_NORM,
GROK_AUTH_ROOT and GROK_CONFIG_DIR.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 96-119: fixGrokAuthPermissions currently swallows chmod/chown
failures by logging them and returning Effect.void, making login appear
successful; remove the swallow so failures propagate: keep the
Effect.tapError(log) if you want diagnostics but drop the Effect.orElse(() =>
Effect.void) (or replace it with a no-op that re-throws/returns the original
failure) so the runCommandWithExitCodes result from fixGrokAuthPermissions (and
its CommandFailedError) bubbles up to abort the login flow; look for function
fixGrokAuthPermissions and the chained Effect.tapError / Effect.orElse calls and
change them accordingly.

In `@packages/lib/src/core/templates-entrypoint/grok.ts`:
- Around line 51-64: In docker_git_link_grok_file, when link_path exists as a
regular file the current logic copies it to source_path and returns early,
leaving link_path as a plain file and breaking auto-sync; change this so after
copying (if source_path doesn't already exist) you always replace link_path with
a symlink to source_path (i.e., remove the early return and run ln -sfn
"$source_path" "$link_path" afterwards), preserving the permission step (chmod
0600 on source_path) and ensuring ln -sfn is used to atomically create/overwrite
the symlink for selected-label state consistency.

In `@packages/lib/tests/core/templates.test.ts`:
- Around line 218-229: The test installs Grok CLI in a way that contradicts the
spec: update the test "installs Grok CLI for generated project containers" (and
the helper usage of renderDockerfile(makeTemplateConfig())) to assert the
intended behavior from the PR/issue (expect "grok-dev@latest" and the original
installer lines like "npm install -g grok-dev" or any legacy fallback), or if
the new pinned official installer ("https://x.ai/cli/install.sh" and pinned
version string) is the intended change, update the PR/issue description and
user-facing docs and change the test assertions to reflect the new installer
contract instead of forbidding "grok-dev". Ensure assertions reference the
relevant strings used in the code (e.g., checks around "grok-dev", "npm install
-g grok-dev", the install script URL, and the pinned version invocation) so the
test matches the documented/specified installer behavior.

---

Duplicate comments:
In `@packages/app/src/lib/core/templates-entrypoint/grok.ts`:
- Around line 29-45: The template reads GROK_AUTH_LABEL directly which breaks
under set -u; update grokAuthConfigTemplate to safely reference the optional env
using shell parameter expansion (e.g. replace GROK_LABEL_RAW="$GROK_AUTH_LABEL"
with GROK_LABEL_RAW="${GROK_AUTH_LABEL:-}" and any other direct uses of
GROK_AUTH_LABEL later in the template/profile/SSH env generation with
${GROK_AUTH_LABEL:-} so the bootstrap won't abort and the existing fallback to
"default" via GROK_LABEL_NORM still applies); ensure changes are made inside the
grokAuthConfigTemplate string containing GROK_LABEL_RAW, GROK_LABEL_NORM,
GROK_AUTH_ROOT and GROK_CONFIG_DIR.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c6f13dfe-6d20-4a5b-adb1-6d0f4ab4db78

📥 Commits

Reviewing files that changed from the base of the PR and between 0f97fc1 and b73a364.

📒 Files selected for processing (5)
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Login context)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/templates.test.ts

Comment thread packages/app/src/lib/usecases/auth-grok-oauth.ts
Comment thread packages/lib/src/core/templates-entrypoint/grok.ts
Comment on lines +218 to +229
it("installs Grok CLI for generated project containers", () => {
const dockerfile = renderDockerfile(makeTemplateConfig())

expectContainsAll(dockerfile, [
"https://x.ai/cli/install.sh",
"GROK_BIN_DIR=/usr/local/bin bash /tmp/grok-install.sh 0.1.211",
"grok --version"
])
expect(dockerfile).not.toContain("grok-dev")
expect(dockerfile).not.toContain("npm install -g grok-dev")
expect(dockerfile).not.toContain("grok --version >/dev/null || true")
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Тест закрепляет поведение, расходящееся с заявленным ТЗ по установке Grok CLI.

В PR objectives и issue #304 явно указан шаблон с grok-dev@latest, а этот тест теперь фиксирует противоположный контракт: официальный install script c pinned-версией и явный запрет на grok-dev. Если переход на другой installer — осознанное решение, это нужно синхронно обновить в issue/PR description и user-facing docs; иначе тест сейчас цементирует неверное поведение.

As per coding guidelines, "Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход от спеки, недокументированное изменение поведения, отсутствие тестов для заявленного поведения и security-риск."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/lib/tests/core/templates.test.ts` around lines 218 - 229, The test
installs Grok CLI in a way that contradicts the spec: update the test "installs
Grok CLI for generated project containers" (and the helper usage of
renderDockerfile(makeTemplateConfig())) to assert the intended behavior from the
PR/issue (expect "grok-dev@latest" and the original installer lines like "npm
install -g grok-dev" or any legacy fallback), or if the new pinned official
installer ("https://x.ai/cli/install.sh" and pinned version string) is the
intended change, update the PR/issue description and user-facing docs and change
the test assertions to reflect the new installer contract instead of forbidding
"grok-dev". Ensure assertions reference the relevant strings used in the code
(e.g., checks around "grok-dev", "npm install -g grok-dev", the install script
URL, and the pinned version invocation) so the test matches the
documented/specified installer behavior.

@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: 0c29c14
Status: success
Files: 10 (24.89 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/lib/usecases/auth-grok-oauth.ts`:
- Around line 90-94: The grokAuthPermissionScript constant currently hardcodes
UID/GID "1000:1000"; change it to determine UID/GID dynamically like the fix in
packages/lib: build the chown operand from the runtime user/group (e.g. use id
-u and id -g or respect environment variables such as CHOWN_UID/CHOWN_GID) and
substitute that value into grokAuthPermissionScript so the chown uses the actual
container/user IDs rather than 1000:1000; update the grokAuthPermissionScript
symbol accordingly and mirror the same implementation approach used in
packages/lib/src/usecases/auth-grok-oauth.ts.

In `@packages/lib/src/usecases/auth-grok-oauth.ts`:
- Around line 90-94: The hardcoded chown in grokAuthPermissionScript (chown -R
1000:1000 "$1") will break in rootless Docker or when sshUser/UID differ; change
grokAuthPermissionScript to determine owner UID/GID dynamically or accept
UID/GID as parameters and use them in the chown command (e.g., mirror the
GROK_SETTINGS_OWNER_UID approach used in
packages/lib/src/core/templates-entrypoint/grok.ts), so that
grokAuthPermissionScript runs chown with the actual runtime owner instead of
1000:1000.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8c13ed0c-c6cf-4784-a6a4-83323786f3e6

📥 Commits

Reviewing files that changed from the base of the PR and between b73a364 and 0c29c14.

📒 Files selected for processing (7)
  • README.md
  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (9)
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • README.md
  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/lib/src/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/lib/tests/core/templates.test.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
  • packages/lib/src/core/templates-entrypoint/grok.ts
**/packages/app/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (README.md)

APP layer (CLI + React Frontend) should only communicate with the API layer and not access LIB directly

Files:

  • packages/app/src/docker-git/cli/usage.ts
  • packages/app/src/lib/usecases/auth-grok-oauth.ts
  • packages/app/src/lib/core/templates-entrypoint/grok.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/lib/tests/core/templates.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/lib/tests/core/templates.test.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:43:12.431Z
Learning: Default project location is `~/.docker-git`
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:43:12.431Z
Learning: Projects should be created for each repository, issue, or PR separately with isolated Docker environments
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:43:12.431Z
Learning: Controller runtime contract requires host-Docker-backed design with bind-mounted `/var/run/docker.sock` for managing per-project containers
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:43:12.431Z
Learning: When CLI cannot acquire Docker access, diagnostic messages must identify the specific failure mode (daemon unreachable, socket permission denied, or controller not running) and provide remediation steps
Learnt from: CR
Repo: ProverCoderAI/docker-git

Timestamp: 2026-05-18T07:43:12.431Z
Learning: Controller diagnostics implementation should be in `packages/app/src/docker-git/controller-docker-diagnostics.ts`
🔇 Additional comments (13)
README.md (1)

28-34: LGTM!

Also applies to: 53-54

packages/app/src/docker-git/cli/usage.ts (1)

37-37: LGTM!

Also applies to: 73-74, 81-81, 114-115, 130-131

packages/lib/src/usecases/auth-grok-oauth.ts (1)

1-56: LGTM!

Also applies to: 57-78, 80-88, 96-118, 120-162

packages/app/src/lib/usecases/auth-grok-oauth.ts (1)

1-56: LGTM!

Also applies to: 57-78, 80-88, 96-118, 120-162

packages/lib/tests/core/templates.test.ts (3)

30-30: LGTM!

Also applies to: 218-229


424-468: LGTM!


489-576: LGTM!

packages/app/src/lib/core/templates-entrypoint/grok.ts (3)

1-145: LGTM!


147-221: LGTM!


223-315: LGTM!

packages/lib/src/core/templates-entrypoint/grok.ts (3)

1-145: LGTM!


146-221: LGTM!


222-313: LGTM!

Comment thread packages/app/src/lib/usecases/auth-grok-oauth.ts
Comment thread packages/lib/src/usecases/auth-grok-oauth.ts
@skulidropek
Copy link
Copy Markdown
Member

skulidropek commented May 18, 2026

AI Session Backup

Commit: bb3f1ba
Status: success
Files: 10 (25.07 MB)
Links: README | Manifest

git status

On branch issue-304-3b5ced26375c
nothing to commit, working tree clean

@skulidropek skulidropek merged commit b323b98 into ProverCoderAI:main May 18, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Реализовать поддержку авторизации grok

2 participants